diff --git a/OpenTelemetry.proj b/OpenTelemetry.proj index 6247d1d6c5c..2cc1c23a6e1 100644 --- a/OpenTelemetry.proj +++ b/OpenTelemetry.proj @@ -2,15 +2,8 @@ - - - - - - - diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index b15e5d2b08f..c1be1565083 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -29,6 +29,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E 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\finalize-publicapi.ps1 = build\finalize-publicapi.ps1 + build\GlobalAttrExclusions.txt = build\GlobalAttrExclusions.txt build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetry.prod.loose.ruleset = build\OpenTelemetry.prod.loose.ruleset build\OpenTelemetry.prod.ruleset = build\OpenTelemetry.prod.ruleset @@ -72,10 +73,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Cons EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Zipkin.Tests", "test\OpenTelemetry.Exporter.Zipkin.Tests\OpenTelemetry.Exporter.Zipkin.Tests.csproj", "{1D778D2E-9523-450E-A6E0-A36897C7E78E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet", "src\OpenTelemetry.Instrumentation.AspNet\OpenTelemetry.Instrumentation.AspNet.csproj", "{B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.Tests", "test\OpenTelemetry.Instrumentation.AspNet.Tests\OpenTelemetry.Instrumentation.AspNet.Tests.csproj", "{55CBAADE-7040-46D6-A845-F207B4F0E281}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests", "test\OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests\OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj", "{7C4026CA-6434-4762-8B77-D657EAEE1325}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F1D0972B-38CF-49C2-9F4B-4C5DE02FB71D}" @@ -126,8 +123,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.ZPages.Tests", "test\OpenTelemetry.Exporter.ZPages.Tests\OpenTelemetry.Exporter.ZPages.Tests.csproj", "{98F9556B-116F-49B5-9211-BB1D418446FF}" 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}") = "Examples.Console", "examples\Console\Examples.Console.csproj", "{FF3E6E08-E8E4-4523-B526-847CD989279F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.AspNetCore", "examples\AspNetCore\Examples.AspNetCore.csproj", "{0935622B-9377-4056-8343-AE6ECDC274CF}" @@ -200,10 +195,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customizing-the-sdk", "docs EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus", "src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj", "{52158A12-E7EF-45A1-859F-06F9B17410CB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule", "src\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj", "{F38E511B-1877-4E8A-8051-7879FC7DF8A4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests", "test\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj", "{4D7201BC-7124-4401-AD65-FAB58A053D45}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "learning-more-instruments", "docs\metrics\learning-more-instruments\learning-more-instruments.csproj", "{E7F491CC-C37E-4A56-9CA7-8F77F59E0614}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started", "docs\metrics\getting-started\getting-started.csproj", "{EA60B549-F712-4ABE-8E44-FCA83B78C06E}" @@ -304,14 +295,6 @@ Global {1D778D2E-9523-450E-A6E0-A36897C7E78E}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D778D2E-9523-450E-A6E0-A36897C7E78E}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D778D2E-9523-450E-A6E0-A36897C7E78E}.Release|Any CPU.Build.0 = Release|Any CPU - {B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Release|Any CPU.Build.0 = Release|Any CPU - {55CBAADE-7040-46D6-A845-F207B4F0E281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55CBAADE-7040-46D6-A845-F207B4F0E281}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55CBAADE-7040-46D6-A845-F207B4F0E281}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55CBAADE-7040-46D6-A845-F207B4F0E281}.Release|Any CPU.Build.0 = Release|Any CPU {7C4026CA-6434-4762-8B77-D657EAEE1325}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7C4026CA-6434-4762-8B77-D657EAEE1325}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C4026CA-6434-4762-8B77-D657EAEE1325}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -324,10 +307,6 @@ Global {98F9556B-116F-49B5-9211-BB1D418446FF}.Debug|Any CPU.Build.0 = Debug|Any CPU {98F9556B-116F-49B5-9211-BB1D418446FF}.Release|Any CPU.ActiveCfg = Release|Any CPU {98F9556B-116F-49B5-9211-BB1D418446FF}.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 {FF3E6E08-E8E4-4523-B526-847CD989279F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FF3E6E08-E8E4-4523-B526-847CD989279F}.Debug|Any CPU.Build.0 = Debug|Any CPU {FF3E6E08-E8E4-4523-B526-847CD989279F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -412,14 +391,6 @@ Global {52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.Build.0 = Debug|Any CPU {52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.ActiveCfg = Release|Any CPU {52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.Build.0 = Release|Any CPU - {F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Release|Any CPU.Build.0 = Release|Any CPU - {4D7201BC-7124-4401-AD65-FAB58A053D45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4D7201BC-7124-4401-AD65-FAB58A053D45}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4D7201BC-7124-4401-AD65-FAB58A053D45}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4D7201BC-7124-4401-AD65-FAB58A053D45}.Release|Any CPU.Build.0 = Release|Any CPU {E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Debug|Any CPU.Build.0 = Debug|Any CPU {E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -489,7 +460,6 @@ Global {E69578EB-B456-4062-A645-877CD964528B} = {F1D0972B-38CF-49C2-9F4B-4C5DE02FB71D} {C1542297-8763-4DF4-957C-489ED771C21D} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD} {D2E73927-5966-445C-94E9-EFE6F269C8D5} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD} - {9A4E3A68-904B-4835-A3C8-F664B73098DB} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E} {FF3E6E08-E8E4-4523-B526-847CD989279F} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E} {0935622B-9377-4056-8343-AE6ECDC274CF} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E} {2C7DD1DA-C229-4D9E-9AF0-BCD5CD3E4948} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD} diff --git a/README.md b/README.md index b7ab73708a0..30ee80bb0df 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,6 @@ Here are the most commonly used components: Here are the [instrumentation libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library): -* [ASP.NET](./src/OpenTelemetry.Instrumentation.AspNet/README.md) * [ASP.NET Core](./src/OpenTelemetry.Instrumentation.AspNetCore/README.md) * [Grpc.Net.Client](./src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md) * [HTTP clients](./src/OpenTelemetry.Instrumentation.Http/README.md) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 45fbfd9505a..7e44a5db0d0 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -37,9 +37,6 @@ [2.43.0,3.0) [2.43.0, 3.0) [2.44.0,3.0) - [5.2.7,6.0) - [5.2.7,6.0) - [3.2.7,4.0) [3.1.6,5.0) [6.0.0,) [6.0.0,) diff --git a/build/Common.prod.props b/build/Common.prod.props index c97f40a0ed9..915644b7755 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -35,6 +35,7 @@ $(Build_ArtifactStagingDirectory) true + $(RepoRoot)\build\GlobalAttrExclusions.txt diff --git a/build/GlobalAttrExclusions.txt b/build/GlobalAttrExclusions.txt new file mode 100644 index 00000000000..eb04262f5e1 --- /dev/null +++ b/build/GlobalAttrExclusions.txt @@ -0,0 +1,4 @@ +// These attributes should be excluded from ApiCompat checks. + +T:System.Runtime.CompilerServices.CompilerGeneratedAttribute +T:System.Runtime.CompilerServices.NullableContextAttribute \ No newline at end of file diff --git a/docs/logs/customizing-the-sdk/Program.cs b/docs/logs/customizing-the-sdk/Program.cs index edaf04e992c..b6b3afd07d8 100644 --- a/docs/logs/customizing-the-sdk/Program.cs +++ b/docs/logs/customizing-the-sdk/Program.cs @@ -30,9 +30,7 @@ public static void Main() builder.AddOpenTelemetry(options => { options.IncludeScopes = true; - options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService( - serviceName: "MyService", - serviceVersion: "1.0.0")); + options.ConfigureResource(r => r.AddService(serviceName: "MyService", serviceVersion: "1.0.0")); options.AddConsoleExporter(); }); }); diff --git a/docs/logs/customizing-the-sdk/README.md b/docs/logs/customizing-the-sdk/README.md index e9cc9e020ef..8b1d9bcb944 100644 --- a/docs/logs/customizing-the-sdk/README.md +++ b/docs/logs/customizing-the-sdk/README.md @@ -52,26 +52,25 @@ var loggerFactory = LoggerFactory.Create(builder => For more information on Processors, please review [Extending the SDK](../extending-the-sdk/README.md#processor) -### SetResourceBuilder +### ConfigureResource [Resource](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md) is the immutable representation of the entity producing the telemetry. If no `Resource` is explicitly configured, the default is to use a resource indicating this [Telemetry SDK](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#telemetry-sdk). -The `SetResourceBuilder` method on `OpenTelemetryLoggerOptions` can be used to -set a single `ResourceBuilder`. If `SetResourceBuilder` is called multiple -times, only the last is kept. It is not possible to change the resource builder +The `ConfigureResource` method on `OpenTelemetryLoggerOptions` can be used to +configure the `ResourceBuilder`. It is not possible to change the resources *after* creating the `LoggerFactory`. -The snippet below shows configuring a custom `ResourceBuilder` to the provider. +The snippet below shows configuring the `ResourceBuilder` of the provider. ```csharp var loggerFactory = LoggerFactory.Create(builder => { builder.AddOpenTelemetry(options => { - options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService( + options.ConfigureResource(r => r.AddService( serviceName: "MyService", serviceVersion: "1.0.0" )); diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index e2b024eeea6..5491faf1914 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -35,9 +35,10 @@ In a typical application, a single `MeterProvider` is created at application startup and disposed at application shutdown. It is important to ensure that the provider is not disposed too early. Actual mechanism depends on the application type. For example, in a typical ASP.NET application, `MeterProvider` is created -in `Application_Start`, and disposed in `Application_End` (both methods part of -Global.asax.cs file) as shown [here](../../../examples/AspNet/Global.asax.cs). In -a typical ASP.NET Core application, `MeterProvider` lifetime is managed by +in `Application_Start`, and disposed in `Application_End` (both methods are a +part of the Global.asax.cs file) as shown +[here](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/examples/AspNet/Global.asax.cs). +In a typical ASP.NET Core application, `MeterProvider` lifetime is managed by leveraging the built-in Dependency Injection container as shown [here](../../../examples/AspNetCore/Program.cs). diff --git a/docs/trace/customizing-the-sdk/README.md b/docs/trace/customizing-the-sdk/README.md index 9587e9c1393..1bac8017d9b 100644 --- a/docs/trace/customizing-the-sdk/README.md +++ b/docs/trace/customizing-the-sdk/README.md @@ -15,9 +15,9 @@ processors, etc. Naturally, almost all the customizations must be done on the Building a `TracerProvider` is done using `TracerProviderBuilder` which must be obtained by calling `Sdk.CreateTracerProviderBuilder()`. `TracerProviderBuilder` -exposes various methods which configures the provider it is going to build. These -includes methods like `SetSampler`, `AddProcessor` etc, and are explained in -subsequent sections of this document. Once configuration is done, calling +exposes various methods which configures the provider it is going to build. +These includes methods like `SetSampler`, `AddProcessor` etc, and are explained +in subsequent sections of this document. Once configuration is done, calling `Build()` on the `TracerProviderBuilder` builds the `TracerProvider` instance. Once built, changes to its configuration is not allowed, with the exception of adding more processors. In most cases, a single `TracerProvider` is created at @@ -38,9 +38,10 @@ In a typical application, a single `TracerProvider` is created at application startup and disposed at application shutdown. It is important to ensure that the provider is not disposed too early. Actual mechanism depends on the application type. For example, in a typical ASP.NET application, `TracerProvider` is created -in `Application_Start`, and disposed in `Application_End` (both methods part of -Global.asax.cs file) as shown [here](../../../examples/AspNet/Global.asax.cs). In -a typical ASP.NET Core application, `TracerProvider` lifetime is managed by +in `Application_Start`, and disposed in `Application_End` (both methods are a +part of the Global.asax.cs file) as shown +[here](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/examples/AspNet/Global.asax.cs). +In a typical ASP.NET Core application, `TracerProvider` lifetime is managed by leveraging the built-in Dependency Injection container as shown [here](../../../examples/AspNetCore/Program.cs). @@ -98,13 +99,12 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() See [Program.cs](./Program.cs) for complete example. -**Note** -A common mistake while configuring `TracerProvider` is forgetting to add -all `ActivitySources` to the provider. It is recommended to leverage the +**Note** A common mistake while configuring `TracerProvider` is forgetting to +add all `ActivitySources` to the provider. It is recommended to leverage the wild card subscription model where it makes sense. For example, if your -application is expecting to enable tracing from a number of libraries -from a company "Abc", the you can use `AddSource("Abc.*")` to enable -all sources whose name starts with "Abc.". +application is expecting to enable tracing from a number of libraries from a +company "Abc", the you can use `AddSource("Abc.*")` to enable all sources whose +name starts with "Abc.". ### Instrumentation @@ -124,5 +124,5 @@ all sources whose name starts with "Abc.". ## Context Propagation -// TODO: OpenTelemetry Sdk contents about Context. -// TODO: Links to built-in instrumentations doing Propagation. +// TODO: OpenTelemetry Sdk contents about Context. // TODO: Links to built-in +instrumentations doing Propagation. diff --git a/docs/trace/extending-the-sdk/MyFilteringProcessor.cs b/docs/trace/extending-the-sdk/MyFilteringProcessor.cs index 22cf898f3b5..ed74678decf 100644 --- a/docs/trace/extending-the-sdk/MyFilteringProcessor.cs +++ b/docs/trace/extending-the-sdk/MyFilteringProcessor.cs @@ -17,16 +17,28 @@ using System; using System.Diagnostics; using OpenTelemetry; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; -internal class MyFilteringProcessor : BaseProcessor +/// +/// A custom processor for filtering instances. +/// +/// +/// Note: is used as the base class because +/// the SDK needs to understand that MyFilteringProcessor wraps an inner +/// processor. Without that understanding some features such as would be unavailable because the SDK needs to push state +/// about the parent to all processors in the +/// chain. +/// +internal sealed class MyFilteringProcessor : CompositeProcessor { private readonly Func filter; - private readonly BaseProcessor processor; public MyFilteringProcessor(BaseProcessor processor, Func filter) + : base(new[] { processor }) { this.filter = filter ?? throw new ArgumentNullException(nameof(filter)); - this.processor = processor ?? throw new ArgumentNullException(nameof(processor)); } public override void OnEnd(Activity activity) @@ -35,7 +47,7 @@ public override void OnEnd(Activity activity) // only if the Filter returns true. if (this.filter(activity)) { - this.processor.OnEnd(activity); + base.OnEnd(activity); } } } diff --git a/docs/trace/extending-the-sdk/README.md b/docs/trace/extending-the-sdk/README.md index 09058fc41fb..d2715f7ded9 100644 --- a/docs/trace/extending-the-sdk/README.md +++ b/docs/trace/extending-the-sdk/README.md @@ -102,7 +102,6 @@ The [OpenTelemetry .NET Github repo](../../../README.md#getting-started) ships the following instrumentation libraries. The individual docs for them describes the library they instrument, and steps for enabling them. -* [ASP.NET](../../../src/OpenTelemetry.Instrumentation.AspNet/README.md) * [ASP.NET Core](../../../src/OpenTelemetry.Instrumentation.AspNetCore/README.md) * [gRPC @@ -200,8 +199,7 @@ activities does not by default runs through the sampler, and will have their `Kind` set to internal and they'll have empty ActivitySource name associated with it. -Some common examples of such libraries include -[ASP.NET](../../../src/OpenTelemetry.Instrumentation.AspNet/README.md), [ASP.NET +Some common examples of such libraries include [ASP.NET Core](../../../src/OpenTelemetry.Instrumentation.AspNetCore/README.md), [HTTP client .NET Core](../../../src/OpenTelemetry.Instrumentation.Http/README.md) . Instrumentation libraries for these are already provided in this repo. The diff --git a/examples/AspNet/App_Start/RouteConfig.cs b/examples/AspNet/App_Start/RouteConfig.cs deleted file mode 100644 index e1c6ae4df10..00000000000 --- a/examples/AspNet/App_Start/RouteConfig.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.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 deleted file mode 100644 index 243637d65d4..00000000000 --- a/examples/AspNet/App_Start/WebApiConfig.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.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 deleted file mode 100644 index f238805897d..00000000000 --- a/examples/AspNet/Controllers/HomeController.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.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 deleted file mode 100644 index 092bdf07104..00000000000 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ /dev/null @@ -1,217 +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.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 deleted file mode 100644 index fe1cd5f2267..00000000000 --- a/examples/AspNet/Examples.AspNet.csproj +++ /dev/null @@ -1,157 +0,0 @@ - - - - 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 - - - - - - - - - - {99f8a331-05e9-45a5-89ba-4c54e825e5b2} - OpenTelemetry.Api - - - {b9eeacdd-cafa-4b75-a18d-898e7de21b17} - OpenTelemetry.Instrumentation.AspNet - - - {8d47e3cf-9ae3-42fe-9084-feb72d9ad769} - OpenTelemetry.Exporter.Jaeger - - - {412c64d1-43d6-4e4c-8ad8-e20e63b415bd} - OpenTelemetry.Instrumentation.Http - - - {ae3e3df5-4083-4c6e-a840-8271b0acde7e} - OpenTelemetry - - - {1afff251-3b0c-47ca-be94-937083732c0a} - OpenTelemetry.Exporter.Console - - - {7edae7fa-b44e-42ca-80fa-7df2faa2c5dd} - OpenTelemetry.Exporter.Zipkin - - - {a38ac295-2745-4b85-8b6b-dca864cedd5b} - OpenTelemetry.Exporter.OpenTelemetryProtocol - - - {52158a12-e7ef-45a1-859f-06f9b17410cb} - OpenTelemetry.Exporter.Prometheus - - - - 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 deleted file mode 100644 index e6d835ed401..00000000000 --- a/examples/AspNet/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ 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 deleted file mode 100644 index 260dda7f92b..00000000000 --- a/examples/AspNet/Global.asax.cs +++ /dev/null @@ -1,111 +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.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/Properties/AssemblyInfo.cs b/examples/AspNet/Properties/AssemblyInfo.cs deleted file mode 100644 index 7dd41a41ac8..00000000000 --- a/examples/AspNet/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,50 +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.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 deleted file mode 100644 index fb832109182..00000000000 --- a/examples/AspNet/SuppressInstrumentationHttpModule.cs +++ /dev/null @@ -1,58 +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.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 deleted file mode 100644 index 4b2d9e8440b..00000000000 --- a/examples/AspNet/Views/Home/About.cshtml +++ /dev/null @@ -1,7 +0,0 @@ -@{ - 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 deleted file mode 100644 index b89b4453d35..00000000000 --- a/examples/AspNet/Views/Home/Index.cshtml +++ /dev/null @@ -1,31 +0,0 @@ -@{ - 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 deleted file mode 100644 index 160995d9616..00000000000 --- a/examples/AspNet/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - @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 deleted file mode 100644 index 6e67a6c67f5..00000000000 --- a/examples/AspNet/Views/Web.config +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/AspNet/Views/_ViewStart.cshtml b/examples/AspNet/Views/_ViewStart.cshtml deleted file mode 100644 index 2de62418c07..00000000000 --- a/examples/AspNet/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "~/Views/Shared/_Layout.cshtml"; -} diff --git a/examples/AspNet/Web.Debug.config b/examples/AspNet/Web.Debug.config deleted file mode 100644 index 104f153f93f..00000000000 --- a/examples/AspNet/Web.Debug.config +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - diff --git a/examples/AspNet/Web.Release.config b/examples/AspNet/Web.Release.config deleted file mode 100644 index 63c58428af0..00000000000 --- a/examples/AspNet/Web.Release.config +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config deleted file mode 100644 index bd4f12f8b14..00000000000 --- a/examples/AspNet/Web.config +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/AspNetCore/Program.cs b/examples/AspNetCore/Program.cs index c507e7df44e..0ee7a24c22a 100644 --- a/examples/AspNetCore/Program.cs +++ b/examples/AspNetCore/Program.cs @@ -24,27 +24,28 @@ var builder = WebApplication.CreateBuilder(args); -var serviceName = "AspNetCoreExampleService"; - // OpenTelemetry var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown"; // Switch between Zipkin/Jaeger/OTLP by setting UseExporter in appsettings.json. var tracingExporter = builder.Configuration.GetValue("UseTracingExporter").ToLowerInvariant(); -var resourceBuilder = tracingExporter switch +var serviceName = tracingExporter switch { - "jaeger" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue("Jaeger:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName), - "zipkin" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue("Zipkin:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName), - "otlp" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue("Otlp:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName), - _ => ResourceBuilder.CreateDefault().AddService(serviceName, serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName), + "jaeger" => builder.Configuration.GetValue("Jaeger:ServiceName"), + "zipkin" => builder.Configuration.GetValue("Zipkin:ServiceName"), + "otlp" => builder.Configuration.GetValue("Otlp:ServiceName"), + _ => "AspNetCoreExampleService", }; +Action configureResource = r => r.AddService( + serviceName, serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName); + // Traces builder.Services.AddOpenTelemetryTracing(options => { options - .SetResourceBuilder(resourceBuilder) + .ConfigureResource(configureResource) .SetSampler(new AlwaysOnSampler()) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation(); @@ -88,7 +89,7 @@ builder.Logging.AddOpenTelemetry(options => { - options.SetResourceBuilder(resourceBuilder); + options.ConfigureResource(configureResource); var logExporter = builder.Configuration.GetValue("UseLogExporter").ToLowerInvariant(); switch (logExporter) { @@ -114,7 +115,7 @@ // Metrics builder.Services.AddOpenTelemetryMetrics(options => { - options.SetResourceBuilder(resourceBuilder) + options.ConfigureResource(configureResource) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation(); diff --git a/examples/Console/Examples.Console.csproj b/examples/Console/Examples.Console.csproj index 26556b21e48..830e6dfe32c 100644 --- a/examples/Console/Examples.Console.csproj +++ b/examples/Console/Examples.Console.csproj @@ -3,7 +3,6 @@ Exe net6.0 - false $(NoWarn),CS0618 diff --git a/examples/Console/TestConsoleExporter.cs b/examples/Console/TestConsoleExporter.cs index 9929beab33b..031e6fc4e09 100644 --- a/examples/Console/TestConsoleExporter.cs +++ b/examples/Console/TestConsoleExporter.cs @@ -39,7 +39,7 @@ private static object RunWithActivitySource() // and use Console exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("Samples.SampleClient", "Samples.SampleServer") - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("console-test")) + .ConfigureResource(res => res.AddService("console-test")) .AddProcessor(new MyProcessor()) // This must be added before ConsoleExporter .AddConsoleExporter() .Build(); diff --git a/examples/Console/TestHttpClient.cs b/examples/Console/TestHttpClient.cs index 734cae06b58..ba122c5f09a 100644 --- a/examples/Console/TestHttpClient.cs +++ b/examples/Console/TestHttpClient.cs @@ -34,7 +34,7 @@ internal static object Run() using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("http-service-example")) + .ConfigureResource(r => r.AddService("http-service-example")) .AddSource("http-client-test") .AddConsoleExporter() .Build(); diff --git a/examples/Console/TestInMemoryExporter.cs b/examples/Console/TestInMemoryExporter.cs index f46ed608bdf..5cfbe327417 100644 --- a/examples/Console/TestInMemoryExporter.cs +++ b/examples/Console/TestInMemoryExporter.cs @@ -51,7 +51,7 @@ private static void RunWithActivitySource(ICollection exportedItems) // and use InMemory exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("Samples.SampleClient", "Samples.SampleServer") - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("inmemory-test")) + .ConfigureResource(r => r.AddService("inmemory-test")) .AddInMemoryExporter(exportedItems) .Build(); diff --git a/examples/Console/TestJaegerExporter.cs b/examples/Console/TestJaegerExporter.cs index 2c67e9bff66..aca3909886e 100644 --- a/examples/Console/TestJaegerExporter.cs +++ b/examples/Console/TestJaegerExporter.cs @@ -56,7 +56,7 @@ internal static object RunWithActivity(string host, int port) // Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient" // and use the Jaeger exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("jaeger-test")) + .ConfigureResource(r => r.AddService("jaeger-test")) .AddSource("Samples.SampleClient", "Samples.SampleServer") .AddJaegerExporter(o => { diff --git a/examples/Console/TestMetrics.cs b/examples/Console/TestMetrics.cs index 35fc3dd1324..78ee9cbed97 100644 --- a/examples/Console/TestMetrics.cs +++ b/examples/Console/TestMetrics.cs @@ -33,7 +33,7 @@ internal static object Run(MetricsOptions options) using var meter = new Meter("TestMeter"); var providerBuilder = Sdk.CreateMeterProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("myservice")) + .ConfigureResource(r => r.AddService("myservice")) .AddMeter(meter.Name); // All instruments from this meter are enabled. if (options.UseExporter.Equals("otlp", StringComparison.OrdinalIgnoreCase)) diff --git a/examples/Console/TestOTelShimWithConsoleExporter.cs b/examples/Console/TestOTelShimWithConsoleExporter.cs index 984ac7ad380..31bb3c85f6b 100644 --- a/examples/Console/TestOTelShimWithConsoleExporter.cs +++ b/examples/Console/TestOTelShimWithConsoleExporter.cs @@ -28,7 +28,7 @@ internal static object Run(OpenTelemetryShimOptions options) // and use a single pipeline with a custom MyProcessor, and Console exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("MyCompany.MyProduct.MyWebServer") - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName")) + .ConfigureResource(r => r.AddService("MyServiceName")) .AddConsoleExporter() .Build(); diff --git a/examples/Console/TestOpenTracingShim.cs b/examples/Console/TestOpenTracingShim.cs index f0e967992a2..7361c3aa4d5 100644 --- a/examples/Console/TestOpenTracingShim.cs +++ b/examples/Console/TestOpenTracingShim.cs @@ -31,7 +31,7 @@ internal static object Run(OpenTracingShimOptions options) // and use Console exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("MyCompany.MyProduct.MyWebServer") - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName")) + .ConfigureResource(r => r.AddService("MyServiceName")) .AddConsoleExporter() .Build(); diff --git a/examples/Console/TestOtlpExporter.cs b/examples/Console/TestOtlpExporter.cs index 3936f1b0ef8..f5417e77c66 100644 --- a/examples/Console/TestOtlpExporter.cs +++ b/examples/Console/TestOtlpExporter.cs @@ -71,7 +71,7 @@ private static object RunWithActivitySource(string endpoint, string protocol) // and use OTLP exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("Samples.SampleClient", "Samples.SampleServer") - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("otlp-test")) + .ConfigureResource(r => r.AddService("otlp-test")) .AddOtlpExporter(opt => { // If endpoint was not specified, the proper one will be selected according to the protocol. diff --git a/examples/Console/TestZipkinExporter.cs b/examples/Console/TestZipkinExporter.cs index 40c44551b84..0f6bbce2272 100644 --- a/examples/Console/TestZipkinExporter.cs +++ b/examples/Console/TestZipkinExporter.cs @@ -39,7 +39,7 @@ internal static object Run(string zipkinUri) // and use the Zipkin exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("Samples.SampleClient", "Samples.SampleServer") - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("zipkin-test")) + .ConfigureResource(r => r.AddService("zipkin-test")) .AddZipkinExporter(o => { o.Endpoint = new Uri(zipkinUri); diff --git a/examples/GrpcService/Startup.cs b/examples/GrpcService/Startup.cs index a2d1adf7e0d..c7034011b02 100644 --- a/examples/GrpcService/Startup.cs +++ b/examples/GrpcService/Startup.cs @@ -45,7 +45,7 @@ public void ConfigureServices(IServiceCollection services) { case "jaeger": services.AddOpenTelemetryTracing((builder) => builder - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue("Jaeger:ServiceName"))) + .ConfigureResource(r => r.AddService(this.Configuration.GetValue("Jaeger:ServiceName"))) .AddAspNetCoreInstrumentation() .AddJaegerExporter(jaegerOptions => { diff --git a/src/OpenTelemetry.Api/README.md b/src/OpenTelemetry.Api/README.md index ab11fd6d734..26da2644258 100644 --- a/src/OpenTelemetry.Api/README.md +++ b/src/OpenTelemetry.Api/README.md @@ -153,8 +153,7 @@ required only for the following scenarios: [Propagators](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md), to inject and extract context data. Some of the most common libraries requiring this include - [HttpClient](../OpenTelemetry.Instrumentation.Http/README.md), - [ASP.NET](../OpenTelemetry.Instrumentation.AspNet/README.md), [ASP.NET + [HttpClient](../OpenTelemetry.Instrumentation.Http/README.md), [ASP.NET Core](../OpenTelemetry.Instrumentation.AspNetCore/README.md). This repo already provides instrumentation for these common libraries. If your library is not built on top of these, and want to leverage propagators, follow the @@ -394,8 +393,8 @@ OpenTelemetry defines a concept called [Status](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status) to be associated with `Activity`. Starting with [DiagnosticSource 6.0](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/6.0.0), -`SetStatus` API on `Activity` can be used to set the status and description -as shown below: +`SetStatus` API on `Activity` can be used to set the status and description as +shown below: ```csharp activity?.SetStatus(ActivityStatusCode.Ok); @@ -467,16 +466,16 @@ runtime itself, as part of the package. This means, users can instrument their applications/libraries to emit metrics by simply using the `System.Diagnostics.DiagnosticSource` package. This package can be used in applications targeting any of the officially supported -versions of [.NET](https://dotnet.microsoft.com/download/dotnet) and -[.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) (an -older Windows-based .NET implementation). +versions of [.NET](https://dotnet.microsoft.com/download/dotnet) and [.NET +Framework](https://dotnet.microsoft.com/download/dotnet-framework) (an older +Windows-based .NET implementation). ## Instrumenting a library/application with .NET Metrics API ### Basic metric usage -1. Install the `System.Diagnostics.DiagnosticSource` package version - `6.0.0` or above to your application or library. +1. Install the `System.Diagnostics.DiagnosticSource` package version `6.0.0` or + above to your application or library. ```xml @@ -496,9 +495,8 @@ older Windows-based .NET implementation). The above requires import of the `System.Diagnostics.Metrics` namespace. - **Note:** - It is important to note that `Meter` instances are created by using its - constructor, and *not* by calling a `GetMeter` method on the + **Note:** It is important to note that `Meter` instances are created by + using its constructor, and *not* by calling a `GetMeter` method on the `MeterProvider`. This is an important distinction from the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#get-a-meter), where `Meter`s are obtained from `MeterProvider`. @@ -528,8 +526,7 @@ describes more kinds of instruments. This component uses an [EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) -with the name "OpenTelemetry-Api" for its internal logging. -Please refer to [SDK +with the name "OpenTelemetry-Api" for its internal logging. Please refer to [SDK troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on seeing these internal logs. diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs index 2e3731e1d3b..c35cf543222 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs @@ -42,7 +42,11 @@ public override ExportResult Export(in Batch batch) this.WriteLine($"{"LogRecord.TraceFlags:",-RightPaddingLength}{logRecord.TraceFlags}"); } - this.WriteLine($"{"LogRecord.CategoryName:",-RightPaddingLength}{logRecord.CategoryName}"); + if (logRecord.CategoryName != null) + { + this.WriteLine($"{"LogRecord.CategoryName:",-RightPaddingLength}{logRecord.CategoryName}"); + } + this.WriteLine($"{"LogRecord.LogLevel:",-RightPaddingLength}{logRecord.LogLevel}"); if (logRecord.FormattedMessage != null) @@ -76,13 +80,13 @@ public override ExportResult Export(in Batch batch) if (logRecord.EventId != default) { this.WriteLine($"{"LogRecord.EventId:",-RightPaddingLength}{logRecord.EventId.Id}"); - if (string.IsNullOrEmpty(logRecord.EventId.Name)) + if (!string.IsNullOrEmpty(logRecord.EventId.Name)) { this.WriteLine($"{"LogRecord.EventName:",-RightPaddingLength}{logRecord.EventId.Name}"); } } - if (logRecord.Exception is { }) + if (logRecord.Exception != null) { this.WriteLine($"{"LogRecord.Exception:",-RightPaddingLength}{logRecord.Exception?.Message}"); } diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index 17fa5bd8c7d..7b528d516d4 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* `InMemoryExporter` will now buffer scopes when exporting `LogRecord` + ([#3360](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3360)) + ## 1.3.0 Released 2022-Jun-03 diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs index 8dab7b51d96..9715119d6b2 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.Collections.Generic; namespace OpenTelemetry.Exporter @@ -23,19 +22,21 @@ public class InMemoryExporter : BaseExporter where T : class { private readonly ICollection exportedItems; - private readonly Func, ExportResult> onExport; + private readonly ExportFunc onExport; public InMemoryExporter(ICollection exportedItems) { this.exportedItems = exportedItems; - this.onExport = (Batch batch) => this.DefaultExport(batch); + this.onExport = this.DefaultExport; } - internal InMemoryExporter(Func, ExportResult> exportFunc) + internal InMemoryExporter(ExportFunc exportFunc) { this.onExport = exportFunc; } + internal delegate ExportResult ExportFunc(in Batch batch); + public override ExportResult Export(in Batch batch) => this.onExport(batch); private ExportResult DefaultExport(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs index 9cbde894ced..ca67d4f3be5 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs @@ -27,7 +27,27 @@ public static OpenTelemetryLoggerOptions AddInMemoryExporter(this OpenTelemetryL Guard.ThrowIfNull(loggerOptions); Guard.ThrowIfNull(exportedItems); - return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(new InMemoryExporter(exportedItems))); + var logExporter = new InMemoryExporter( + exportFunc: (in Batch batch) => ExportLogRecord(in batch, exportedItems)); + + return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(logExporter)); + } + + private static ExportResult ExportLogRecord(in Batch batch, ICollection exportedItems) + { + if (exportedItems == null) + { + return ExportResult.Failure; + } + + foreach (var log in batch) + { + log.BufferLogScopes(); + + exportedItems.Add(log); + } + + return ExportResult.Success; } } } diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs index f817f5744fa..613067d5e8a 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs @@ -145,7 +145,7 @@ private static MeterProviderBuilder AddInMemoryExporter( configureMetricReader?.Invoke(metricReaderOptions); var metricExporter = new InMemoryExporter( - exportFunc: metricBatch => ExportMetricSnapshot(metricBatch, exportedItems)); + exportFunc: (in Batch metricBatch) => ExportMetricSnapshot(in metricBatch, exportedItems)); var metricReader = PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader( metricExporter, diff --git a/src/OpenTelemetry.Extensions.Propagators/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Propagators/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2d..ee1db2f0d31 100644 --- a/src/OpenTelemetry.Extensions.Propagators/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Propagators/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Extensions.Propagators.JaegerPropagator +OpenTelemetry.Extensions.Propagators.JaegerPropagator.JaegerPropagator() -> void +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Fields.get -> System.Collections.Generic.ISet +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void diff --git a/src/OpenTelemetry.Extensions.Propagators/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Propagators/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..ee1db2f0d31 100644 --- a/src/OpenTelemetry.Extensions.Propagators/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Propagators/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Extensions.Propagators.JaegerPropagator +OpenTelemetry.Extensions.Propagators.JaegerPropagator.JaegerPropagator() -> void +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Fields.get -> System.Collections.Generic.ISet +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void diff --git a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md index 1e23a998e58..b8ded0360f5 100644 --- a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add `JaegerPropagator`. + ([1881](https://github.com/open-telemetry/opentelemetry-dotnet/issues/1881)) + ## 1.3.0 Released 2022-Jun-03 diff --git a/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs b/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs new file mode 100644 index 00000000000..a3fa2e98da5 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.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; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Extensions.Propagators; + +/// +/// A text map propagator for Jaeger trace context. See https://www.jaegertracing.io/docs/next-release/client-libraries/#propagation-format. +/// +public class JaegerPropagator : TextMapPropagator +{ + internal const string JaegerHeader = "uber-trace-id"; + internal const string JaegerDelimiter = ":"; + internal const string JaegerDelimiterEncoded = "%3A"; // while the spec defines the delimiter as a ':', some clients will url encode headers. + internal const string SampledValue = "1"; + + internal static readonly string[] JaegerDelimiters = { JaegerDelimiter, JaegerDelimiterEncoded }; + + private static readonly int TraceId128BitLength = "0af7651916cd43dd8448eb211c80319c".Length; + private static readonly int SpanIdLength = "00f067aa0ba902b7".Length; + + /// + public override ISet Fields => new HashSet { JaegerHeader }; + + /// + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + { + if (context.ActivityContext.IsValid()) + { + // If a valid context has already been extracted, perform a noop. + return context; + } + + if (carrier == null) + { + OpenTelemetryPropagatorsEventSource.Log.FailedToExtractActivityContext(nameof(JaegerPropagator), "null carrier"); + return context; + } + + if (getter == null) + { + OpenTelemetryPropagatorsEventSource.Log.FailedToExtractActivityContext(nameof(JaegerPropagator), "null getter"); + return context; + } + + try + { + var jaegerHeaderCollection = getter(carrier, JaegerHeader); + var jaegerHeader = jaegerHeaderCollection?.First(); + + if (string.IsNullOrWhiteSpace(jaegerHeader)) + { + return context; + } + + var jaegerHeaderParsed = TryExtractTraceContext(jaegerHeader, out var traceId, out var spanId, out var traceOptions); + + if (!jaegerHeaderParsed) + { + return context; + } + + return new PropagationContext( + new ActivityContext(traceId, spanId, traceOptions, isRemote: true), + context.Baggage); + } + catch (Exception ex) + { + OpenTelemetryPropagatorsEventSource.Log.ActivityContextExtractException(nameof(JaegerPropagator), ex); + } + + return context; + } + + /// + public override void Inject(PropagationContext context, T carrier, Action setter) + { + // from https://www.jaegertracing.io/docs/next-release/client-libraries/#propagation-format + // parent id is optional and deprecated, will not attempt to set it. + // 128 bit uber-trace-id=e0ad975be108cd107990683f59cda9e6:e422f3fe664f6342:0:1 + const string defaultParentSpanId = "0"; + + if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default) + { + OpenTelemetryPropagatorsEventSource.Log.FailedToInjectActivityContext(nameof(JaegerPropagator), "Invalid context"); + return; + } + + if (carrier == null) + { + OpenTelemetryPropagatorsEventSource.Log.FailedToInjectActivityContext(nameof(JaegerPropagator), "null carrier"); + return; + } + + if (setter == null) + { + OpenTelemetryPropagatorsEventSource.Log.FailedToInjectActivityContext(nameof(JaegerPropagator), "null setter"); + return; + } + + var flags = (context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0 ? "1" : "0"; + + var jaegerTrace = string.Join( + JaegerDelimiter, + context.ActivityContext.TraceId.ToHexString(), + context.ActivityContext.SpanId.ToHexString(), + defaultParentSpanId, + flags); + + setter(carrier, JaegerHeader, jaegerTrace); + } + + internal static bool TryExtractTraceContext(string jaegerHeader, out ActivityTraceId traceId, out ActivitySpanId spanId, out ActivityTraceFlags traceOptions) + { + // from https://www.jaegertracing.io/docs/next-release/client-libraries/#propagation-format + // parent id is optional and deprecated. will not attempt to store it. + // 128 bit uber-trace-id=e0ad975be108cd107990683f59cda9e6:e422f3fe664f6342:0:1 + // 128 bit with encoded delimiter uber-trace-id=e0ad975be108cd107990683f59cda9e6%3Ae422f3fe664f6342%3A0%3A1 + // 64 bit uber-trace-id=7990683f59cda9e6:e422f3fe664f6342:0:1 + // 64 bit with encoded delimiter uber-trace-id=7990683f59cda9e6%3Ae422f3fe664f6342%3A0%3A1 + + traceId = default; + spanId = default; + traceOptions = ActivityTraceFlags.None; + + if (string.IsNullOrWhiteSpace(jaegerHeader)) + { + return false; + } + + var traceComponents = jaegerHeader.Split(JaegerDelimiters, StringSplitOptions.RemoveEmptyEntries); + if (traceComponents.Length != 4) + { + return false; + } + + var traceIdStr = traceComponents[0]; + if (traceIdStr.Length < TraceId128BitLength) + { + traceIdStr = traceIdStr.PadLeft(TraceId128BitLength, '0'); + } + + traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan()); + + var spanIdStr = traceComponents[1]; + if (spanIdStr.Length < SpanIdLength) + { + spanIdStr = spanIdStr.PadLeft(SpanIdLength, '0'); + } + + spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan()); + + var traceFlagsStr = traceComponents[3]; + if (SampledValue.Equals(traceFlagsStr)) + { + traceOptions |= ActivityTraceFlags.Recorded; + } + + return true; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index 367f7a1e6e6..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,16 +0,0 @@ -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 deleted file mode 100644 index 4a1e648ad0c..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ /dev/null @@ -1,224 +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.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 deleted file mode 100644 index 3fd4e239d0e..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs +++ /dev/null @@ -1,122 +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.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 deleted file mode 100644 index 5f10011c2fd..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.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.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 deleted file mode 100644 index fbb62f7ebbc..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ /dev/null @@ -1,59 +0,0 @@ -# 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 deleted file mode 100644 index 924be5d245a..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - 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 deleted file mode 100644 index c2d88b999b0..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# 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 deleted file mode 100644 index 395c5aec12a..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ /dev/null @@ -1,147 +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.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 deleted file mode 100644 index 2d0e42efb01..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs +++ /dev/null @@ -1,67 +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.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 deleted file mode 100644 index 6605354657d..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.install.xdt +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt deleted file mode 100644 index 5b76f2bc420..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 5f282702bb0..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ - \ 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 deleted file mode 100644 index a9ba7f916db..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,12 +0,0 @@ -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 deleted file mode 100644 index 2bd2a988be7..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.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 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 deleted file mode 100644 index 4209ce23e05..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs +++ /dev/null @@ -1,63 +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.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 deleted file mode 100644 index 373fe8a5534..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ /dev/null @@ -1,53 +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.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 deleted file mode 100644 index 0f14529a443..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/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.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 deleted file mode 100644 index 9f6c1880f32..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ /dev/null @@ -1,162 +0,0 @@ -# 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 deleted file mode 100644 index 58bd374d2a5..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs +++ /dev/null @@ -1,67 +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.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 deleted file mode 100644 index 946de293ebf..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ /dev/null @@ -1,197 +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.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 deleted file mode 100644 index ece456273ce..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.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.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 deleted file mode 100644 index e92740546af..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs +++ /dev/null @@ -1,42 +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.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 deleted file mode 100644 index 4e80d0a18f6..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net462 - ASP.NET instrumentation for OpenTelemetry .NET - $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI - true - - - - - - - - - - - - - - - - - diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md deleted file mode 100644 index 3a2ed2c1b7f..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# 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 deleted file mode 100644 index b58aeb83b88..00000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ /dev/null @@ -1,49 +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.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/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 66e2bf0f8bc..d2d2fcbd283 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,13 +2,20 @@ ## Unreleased +* 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.schema' 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. diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 8e80800d159..1ff80acc8b2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -153,8 +153,10 @@ public override void OnStartActivity(Activity activity, object payload) } activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); + activity.SetTag(SemanticConventions.AttributeHttpScheme, request.Scheme); activity.SetTag(SemanticConventions.AttributeHttpTarget, path); activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUri(request)); + activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(request.Protocol)); var userAgent = request.Headers["User-Agent"].FirstOrDefault(); if (!string.IsNullOrEmpty(userAgent)) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index 2becf9cf128..6d99477051f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -78,7 +78,7 @@ public override void OnStopActivity(Activity activity, object payload) { tags = new TagList { - { SemanticConventions.AttributeHttpFlavor, context.Request.Protocol }, + { SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol) }, { SemanticConventions.AttributeHttpScheme, context.Request.Scheme }, { SemanticConventions.AttributeHttpMethod, context.Request.Method }, { SemanticConventions.AttributeHttpHost, host }, @@ -90,7 +90,7 @@ public override void OnStopActivity(Activity activity, object payload) { tags = new TagList { - { SemanticConventions.AttributeHttpFlavor, context.Request.Protocol }, + { SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol) }, { SemanticConventions.AttributeHttpScheme, context.Request.Scheme }, { SemanticConventions.AttributeHttpMethod, context.Request.Method }, { SemanticConventions.AttributeHttpHost, host }, diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpTagHelper.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpTagHelper.cs new file mode 100644 index 00000000000..73114efe0b3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpTagHelper.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. +// + +namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation +{ + /// + /// A collection of helper methods to be used when building Http activities. + /// + internal static class HttpTagHelper + { + /// + /// Gets the OpenTelemetry standard version tag value for a span based on its protocol/>. + /// + /// . + /// Span flavor value. + public static string GetFlavorTagValueFromProtocol(string protocol) + { + switch (protocol) + { + case "HTTP/2": + return "2.0"; + + case "HTTP/3": + return "3.0"; + + case "HTTP/1.1": + return "1.1"; + + default: + return protocol; + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt index b4630d8b7a4..f303cf77aae 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt @@ -6,8 +6,6 @@ OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.set - OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.HttpClientInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.SetHttpFlavor.get -> bool -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.SetHttpFlavor.set -> void OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Enrich.get -> System.Action OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Enrich.set -> void @@ -16,8 +14,6 @@ OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Filter.s OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.HttpWebRequestInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.SetHttpFlavor.get -> bool -OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.SetHttpFlavor.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 04b9e3c9f61..8ac18d7a6e1 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,8 +6,6 @@ OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.set - OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.HttpClientInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.SetHttpFlavor.get -> bool -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.SetHttpFlavor.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index bcdbd2972fb..2c22ca8c063 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +* [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 diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs index d7552aafe14..6206cfee3c8 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs @@ -19,7 +19,6 @@ using System.Net.Http; using System.Runtime.CompilerServices; using OpenTelemetry.Instrumentation.Http.Implementation; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Http { @@ -28,11 +27,6 @@ namespace OpenTelemetry.Instrumentation.Http /// public class HttpClientInstrumentationOptions { - /// - /// Gets or sets a value indicating whether or not the HTTP version should be added as the tag. Default value: False. - /// - public bool SetHttpFlavor { get; set; } - /// /// 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 HttpRequestMessage, and should return a boolean. diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs index 70bf229068d..b695aebf367 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs @@ -19,7 +19,6 @@ using System.Diagnostics; using System.Net; using OpenTelemetry.Instrumentation.Http.Implementation; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Http { @@ -28,11 +27,6 @@ namespace OpenTelemetry.Instrumentation.Http /// public class HttpWebRequestInstrumentationOptions { - /// - /// Gets or sets a value indicating whether or not the HTTP version should be added as the tag. Default value: False. - /// - public bool SetHttpFlavor { get; set; } - /// /// 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 HttpWebRequest, and should return a boolean. diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index c07cf4ecd72..428cce5701f 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -17,7 +17,6 @@ using System; using System.Diagnostics; using System.Net.Http; -using System.Net.Sockets; using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -115,10 +114,7 @@ public override void OnStartActivity(Activity activity, object payload) activity.SetTag(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)); activity.SetTag(SemanticConventions.AttributeHttpHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri)); activity.SetTag(SemanticConventions.AttributeHttpUrl, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri)); - if (this.options.SetHttpFlavor) - { - activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)); - } + activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)); try { @@ -197,20 +193,7 @@ public override void OnException(Activity activity, object payload) if (exc is HttpRequestException) { - if (exc.InnerException is SocketException exception) - { - switch (exception.SocketErrorCode) - { - case SocketError.HostNotFound: - activity.SetStatus(Status.Error.WithDescription(exc.Message)); - return; - } - } - - if (exc.InnerException != null) - { - activity.SetStatus(Status.Error.WithDescription(exc.Message)); - } + activity.SetStatus(Status.Error.WithDescription(exc.Message)); } try diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index 17427bf10c3..f9c9e303b59 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -99,10 +99,7 @@ private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, A activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); activity.SetTag(SemanticConventions.AttributeHttpHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri)); activity.SetTag(SemanticConventions.AttributeHttpUrl, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri)); - if (Options.SetHttpFlavor) - { - activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion)); - } + activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion)); try { diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 8cdad77f0af..8608d970e9d 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -3,8 +3,8 @@ [![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), +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 @@ -27,7 +27,8 @@ is released, there can be breaking changes. You can track the progress from ### Step 1: Install Package -Add a reference to the [`OpenTelemetry.Instrumentation.Http`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) +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 @@ -38,9 +39,9 @@ dotnet add package OpenTelemetry.Instrumentation.Http HTTP instrumentation must be enabled at application startup. -The following example demonstrates adding HTTP instrumentation to a -console application. This example also sets up the OpenTelemetry Console -exporter, which requires adding the package +The following example demonstrates adding HTTP 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. @@ -59,12 +60,13 @@ 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 +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). +`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 @@ -80,9 +82,9 @@ is used. ### SetHttpFlavor By default, this instrumentation does not add the `http.flavor` attribute. The -`http.flavor` attribute specifies the kind of HTTP protocol used -(e.g., `1.1` for HTTP 1.1). The `SetHttpFlavor` option can be used to include -the `http.flavor` attribute. +`http.flavor` attribute specifies the kind of HTTP protocol used (e.g., `1.1` +for HTTP 1.1). The `SetHttpFlavor` option can be used to include the +`http.flavor` attribute. The following example shows how to use `SetHttpFlavor`. @@ -104,8 +106,7 @@ the condition for allowable requests. The Filter receives the request object - representing the outgoing 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. +The following code snippet shows how to use `Filter` to only allow GET requests. ```csharp using var tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -142,8 +143,7 @@ For event name "OnStartActivity", the actual object will be For event name "OnStopActivity", the actual object will be `HttpResponseMessage`. -For event name "OnException", the actual object will be -`Exception`. +For event name "OnException", the actual object will be `Exception`. Example: @@ -180,14 +180,11 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() #### HttpWebRequestInstrumentationOptions -For event name "OnStartActivity", the actual object will be -`HttpWebRequest`. +For event name "OnStartActivity", the actual object will be `HttpWebRequest`. -For event name "OnStopActivity", the actual object will be -`HttpWebResponse`. +For event name "OnStopActivity", the actual object will be `HttpWebResponse`. -For event name "OnException", the actual object will be -`Exception`. +For event name "OnException", the actual object will be `Exception`. Example: @@ -222,10 +219,10 @@ 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 access to raw request, response, and exception objects. +[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 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index d305be1b03a..82005adc737 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -3,8 +3,8 @@ [![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), +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 @@ -37,9 +37,9 @@ dotnet add package 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 +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. @@ -58,12 +58,13 @@ 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 +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). +`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 @@ -72,8 +73,9 @@ This instrumentation can be configured to change the default behavior by using ### Capturing 'db.statement' -The `SqlClientInstrumentationOptions` 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) +The `SqlClientInstrumentationOptions` 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) attribute is captured upon execution of a query. #### .NET Core - SetDbStatementForStoredProcedure and SetDbStatementForText @@ -88,7 +90,8 @@ 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/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md#call-level-attributes) +`true`, the instrumentation will set +[`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md#call-level-attributes) attribute to the text of the SQL command being executed. To disable capturing stored procedure commands use configuration like below. @@ -118,8 +121,8 @@ For .NET Framework, `SetDbStatementForStoredProcedure` and `SetDbStatementForText` are not available. Instead, a single `SetDbStatement` property should 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) -attribute to the text of the `SqlCommand` being executed. This could either be -a name of a stored procedure or a full text of a `CommandType.Text` query. +attribute to the text of the `SqlCommand` being executed. This could either be a +name of a stored procedure or a full text of a `CommandType.Text` query. On .NET Framework, unlike .NET Core, the instrumentation capabilities for both [`Microsoft.Data.SqlClient`](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) @@ -133,8 +136,8 @@ and `System.Data.SqlClient` are limited: query text. 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 +_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: @@ -169,11 +172,11 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() ## Enrich -This option, available on .NET Core only, allows one 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. +This option, available on .NET Core only, allows one 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 @@ -197,15 +200,16 @@ 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 access to `SqlCommand` object. +[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 -This option, available on .NET Core only, can be set to instruct the instrumentation -to record SqlExceptions as Activity [events](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md). +This option, available on .NET Core only, can be set to instruct the +instrumentation to record SqlExceptions as Activity +[events](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md). The default value is `false` and can be changed by the code like below. @@ -221,4 +225,5 @@ 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 database + calls](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt index 56774a7fc4d..afa4f5a68a7 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt @@ -1,21 +1,21 @@ #nullable enable -~abstract OpenTelemetry.BaseExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -~abstract OpenTelemetry.BaseExportProcessor.OnExport(T data) -> void -~OpenTelemetry.BaseExporter -~OpenTelemetry.BaseExporter.ParentProvider.get -> OpenTelemetry.BaseProvider -~OpenTelemetry.BaseExportProcessor -~OpenTelemetry.BaseExportProcessor.BaseExportProcessor(OpenTelemetry.BaseExporter exporter) -> void -~OpenTelemetry.BaseProcessor.ParentProvider.get -> OpenTelemetry.BaseProvider -~OpenTelemetry.Batch -~OpenTelemetry.Batch.Batch(T[] items, int count) -> void -~OpenTelemetry.Batch.Enumerator.Current.get -> T +abstract OpenTelemetry.BaseExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +abstract OpenTelemetry.BaseExportProcessor.OnExport(T! data) -> void +OpenTelemetry.BaseExporter +OpenTelemetry.BaseExporter.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.BaseExportProcessor +OpenTelemetry.BaseExportProcessor.BaseExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +OpenTelemetry.BaseProcessor.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.Batch +OpenTelemetry.Batch.Batch(T![]! items, int count) -> void +OpenTelemetry.Batch.Enumerator.Current.get -> T! ~OpenTelemetry.Batch.GetEnumerator() -> OpenTelemetry.Batch.Enumerator ~OpenTelemetry.BatchActivityExportProcessor.BatchActivityExportProcessor(OpenTelemetry.BaseExporter exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void -~OpenTelemetry.BatchExportProcessor -~OpenTelemetry.BatchExportProcessor.BatchExportProcessor(OpenTelemetry.BaseExporter exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +OpenTelemetry.BatchExportProcessor +OpenTelemetry.BatchExportProcessor.BatchExportProcessor(OpenTelemetry.BaseExporter! exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void ~OpenTelemetry.BatchExportProcessorOptions -~OpenTelemetry.CompositeProcessor.AddProcessor(OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.CompositeProcessor -~OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generic.IEnumerable> processors) -> void +OpenTelemetry.CompositeProcessor.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.CompositeProcessor! +OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generic.IEnumerable!>! processors) -> void ~OpenTelemetry.Metrics.BaseExportingMetricReader.BaseExportingMetricReader(OpenTelemetry.BaseExporter exporter) -> void ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.get -> double[] ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void @@ -46,8 +46,8 @@ ~OpenTelemetry.Resources.ResourceBuilder.Build() -> OpenTelemetry.Resources.Resource ~OpenTelemetry.Resources.ResourceBuilder.Clear() -> OpenTelemetry.Resources.ResourceBuilder ~OpenTelemetry.SimpleActivityExportProcessor.SimpleActivityExportProcessor(OpenTelemetry.BaseExporter exporter) -> void -~OpenTelemetry.SimpleExportProcessor -~OpenTelemetry.SimpleExportProcessor.SimpleExportProcessor(OpenTelemetry.BaseExporter exporter) -> void +OpenTelemetry.SimpleExportProcessor +OpenTelemetry.SimpleExportProcessor.SimpleExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void ~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler) -> void ~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void ~OpenTelemetry.Trace.Sampler.Description.get -> string @@ -60,19 +60,19 @@ ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes) -> void ~OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder ~OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider -~override OpenTelemetry.BaseExportProcessor.OnEnd(T data) -> void +override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void -~override OpenTelemetry.BatchExportProcessor.OnExport(T data) -> void +override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder ~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void -~override OpenTelemetry.SimpleExportProcessor.OnExport(T data) -> void +override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool ~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder ~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddLegacySource(string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder ~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder -~override sealed OpenTelemetry.BaseExportProcessor.OnStart(T data) -> void -~readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter +override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void +readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter ~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder ~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder @@ -145,7 +145,7 @@ OpenTelemetry.ExportResult OpenTelemetry.ExportResult.Failure = 1 -> OpenTelemetry.ExportResult OpenTelemetry.ExportResult.Success = 0 -> OpenTelemetry.ExportResult OpenTelemetry.Logs.LogRecord -OpenTelemetry.Logs.LogRecord.CategoryName.get -> string! +OpenTelemetry.Logs.LogRecord.CategoryName.get -> string? OpenTelemetry.Logs.LogRecord.EventId.get -> Microsoft.Extensions.Logging.EventId OpenTelemetry.Logs.LogRecord.Exception.get -> System.Exception? OpenTelemetry.Logs.LogRecord.ForEachScope(System.Action! callback, TState state) -> void diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2d..ecaf006aa47 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Logs.LogRecord.CategoryName.set -> void +OpenTelemetry.Logs.LogRecord.EventId.set -> void +OpenTelemetry.Logs.LogRecord.Exception.set -> void +OpenTelemetry.Logs.LogRecord.LogLevel.set -> void +OpenTelemetry.Logs.LogRecord.SpanId.set -> void +OpenTelemetry.Logs.LogRecord.Timestamp.set -> void +OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void +OpenTelemetry.Logs.LogRecord.TraceId.set -> void +OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 00000000000..afa4f5a68a7 --- /dev/null +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1,359 @@ +#nullable enable +abstract OpenTelemetry.BaseExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +abstract OpenTelemetry.BaseExportProcessor.OnExport(T! data) -> void +OpenTelemetry.BaseExporter +OpenTelemetry.BaseExporter.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.BaseExportProcessor +OpenTelemetry.BaseExportProcessor.BaseExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +OpenTelemetry.BaseProcessor.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.Batch +OpenTelemetry.Batch.Batch(T![]! items, int count) -> void +OpenTelemetry.Batch.Enumerator.Current.get -> T! +~OpenTelemetry.Batch.GetEnumerator() -> OpenTelemetry.Batch.Enumerator +~OpenTelemetry.BatchActivityExportProcessor.BatchActivityExportProcessor(OpenTelemetry.BaseExporter exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +OpenTelemetry.BatchExportProcessor +OpenTelemetry.BatchExportProcessor.BatchExportProcessor(OpenTelemetry.BaseExporter! exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +~OpenTelemetry.BatchExportProcessorOptions +OpenTelemetry.CompositeProcessor.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.CompositeProcessor! +OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generic.IEnumerable!>! processors) -> void +~OpenTelemetry.Metrics.BaseExportingMetricReader.BaseExportingMetricReader(OpenTelemetry.BaseExporter exporter) -> void +~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.get -> double[] +~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void +~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func +~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void +~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +~OpenTelemetry.Metrics.Metric.Description.get -> string +~OpenTelemetry.Metrics.Metric.MeterName.get -> string +~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string +~OpenTelemetry.Metrics.Metric.Name.get -> string +~OpenTelemetry.Metrics.Metric.Unit.get -> string +~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets +~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions +~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string +~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void +~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string +~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.set -> void +~OpenTelemetry.Metrics.MetricStreamConfiguration.TagKeys.get -> string[] +~OpenTelemetry.Metrics.MetricStreamConfiguration.TagKeys.set -> void +~OpenTelemetry.Metrics.PeriodicExportingMetricReader.PeriodicExportingMetricReader(OpenTelemetry.BaseExporter exporter, int exportIntervalMilliseconds = 60000, int exportTimeoutMilliseconds = 30000) -> void +~OpenTelemetry.ReadOnlyTagCollection.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair +~OpenTelemetry.Resources.IResourceDetector.Detect() -> OpenTelemetry.Resources.Resource +~OpenTelemetry.Resources.Resource.Attributes.get -> System.Collections.Generic.IEnumerable> +~OpenTelemetry.Resources.Resource.Merge(OpenTelemetry.Resources.Resource other) -> OpenTelemetry.Resources.Resource +~OpenTelemetry.Resources.Resource.Resource(System.Collections.Generic.IEnumerable> attributes) -> void +~OpenTelemetry.Resources.ResourceBuilder.AddDetector(OpenTelemetry.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder +~OpenTelemetry.Resources.ResourceBuilder.Build() -> OpenTelemetry.Resources.Resource +~OpenTelemetry.Resources.ResourceBuilder.Clear() -> OpenTelemetry.Resources.ResourceBuilder +~OpenTelemetry.SimpleActivityExportProcessor.SimpleActivityExportProcessor(OpenTelemetry.BaseExporter exporter) -> void +OpenTelemetry.SimpleExportProcessor +OpenTelemetry.SimpleExportProcessor.SimpleExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler) -> void +~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void +~OpenTelemetry.Trace.Sampler.Description.get -> string +~OpenTelemetry.Trace.Sampler.Description.set -> void +~OpenTelemetry.Trace.SamplingParameters.Links.get -> System.Collections.Generic.IEnumerable +~OpenTelemetry.Trace.SamplingParameters.Name.get -> string +~OpenTelemetry.Trace.SamplingParameters.SamplingParameters(System.Diagnostics.ActivityContext parentContext, System.Diagnostics.ActivityTraceId traceId, string name, System.Diagnostics.ActivityKind kind, System.Collections.Generic.IEnumerable> tags = null, System.Collections.Generic.IEnumerable links = null) -> void +~OpenTelemetry.Trace.SamplingParameters.Tags.get -> System.Collections.Generic.IEnumerable> +~OpenTelemetry.Trace.SamplingResult.Attributes.get -> System.Collections.Generic.IEnumerable> +~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes) -> void +~OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +~OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider +override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void +~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void +override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void +override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void +~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool +~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddLegacySource(string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder +~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder +override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void +readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! +~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool +~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool +~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration +~static OpenTelemetry.ProviderExtensions.GetDefaultResource(this OpenTelemetry.BaseProvider baseProvider) -> OpenTelemetry.Resources.Resource +~static OpenTelemetry.ProviderExtensions.GetResource(this OpenTelemetry.BaseProvider baseProvider) -> OpenTelemetry.Resources.Resource +~static OpenTelemetry.Resources.Resource.Empty.get -> OpenTelemetry.Resources.Resource +~static OpenTelemetry.Resources.ResourceBuilder.CreateDefault() -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilder.CreateEmpty() -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddAttributes(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, System.Collections.Generic.IEnumerable> attributes) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddEnvironmentVariableDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddService(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, string serviceName, string serviceNamespace = null, string serviceVersion = null, bool autoGenerateServiceInstanceId = true, string serviceInstanceId = null) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddTelemetrySdk(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator textMapPropagator) -> void +~static OpenTelemetry.SuppressInstrumentationScope.Begin(bool value = true) -> System.IDisposable +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProvider +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetErrorStatusOnException(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, bool enabled = true) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetSampler(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.Trace.Sampler sampler) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProvider provider, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProvider +~static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool +~static OpenTelemetry.Trace.TracerProviderExtensions.Shutdown(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool +abstract OpenTelemetry.Trace.Sampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions +OpenTelemetry.BaseExporter.BaseExporter() -> void +OpenTelemetry.BaseExporter.Dispose() -> void +OpenTelemetry.BaseExporter.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.BaseExporter.Shutdown(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.BaseProcessor +OpenTelemetry.BaseProcessor.BaseProcessor() -> void +OpenTelemetry.BaseProcessor.Dispose() -> void +OpenTelemetry.BaseProcessor.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.BaseProcessor.Shutdown(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Batch.Batch() -> void +OpenTelemetry.Batch.Count.get -> long +OpenTelemetry.Batch.Dispose() -> void +OpenTelemetry.Batch.Enumerator +OpenTelemetry.Batch.Enumerator.Dispose() -> void +OpenTelemetry.Batch.Enumerator.Enumerator() -> void +OpenTelemetry.Batch.Enumerator.MoveNext() -> bool +OpenTelemetry.Batch.Enumerator.Reset() -> void +OpenTelemetry.BatchActivityExportProcessor +OpenTelemetry.BatchExportProcessorOptions.BatchExportProcessorOptions() -> void +OpenTelemetry.BatchExportProcessorOptions.ExporterTimeoutMilliseconds.get -> int +OpenTelemetry.BatchExportProcessorOptions.ExporterTimeoutMilliseconds.set -> void +OpenTelemetry.BatchExportProcessorOptions.MaxExportBatchSize.get -> int +OpenTelemetry.BatchExportProcessorOptions.MaxExportBatchSize.set -> void +OpenTelemetry.BatchExportProcessorOptions.MaxQueueSize.get -> int +OpenTelemetry.BatchExportProcessorOptions.MaxQueueSize.set -> void +OpenTelemetry.BatchExportProcessorOptions.ScheduledDelayMilliseconds.get -> int +OpenTelemetry.BatchExportProcessorOptions.ScheduledDelayMilliseconds.set -> void +OpenTelemetry.BatchLogRecordExportProcessor +OpenTelemetry.BatchLogRecordExportProcessor.BatchLogRecordExportProcessor(OpenTelemetry.BaseExporter! exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +OpenTelemetry.CompositeProcessor +OpenTelemetry.ExportProcessorType +OpenTelemetry.ExportProcessorType.Batch = 1 -> OpenTelemetry.ExportProcessorType +OpenTelemetry.ExportProcessorType.Simple = 0 -> OpenTelemetry.ExportProcessorType +OpenTelemetry.ExportResult +OpenTelemetry.ExportResult.Failure = 1 -> OpenTelemetry.ExportResult +OpenTelemetry.ExportResult.Success = 0 -> OpenTelemetry.ExportResult +OpenTelemetry.Logs.LogRecord +OpenTelemetry.Logs.LogRecord.CategoryName.get -> string? +OpenTelemetry.Logs.LogRecord.EventId.get -> Microsoft.Extensions.Logging.EventId +OpenTelemetry.Logs.LogRecord.Exception.get -> System.Exception? +OpenTelemetry.Logs.LogRecord.ForEachScope(System.Action! callback, TState state) -> void +OpenTelemetry.Logs.LogRecord.FormattedMessage.get -> string? +OpenTelemetry.Logs.LogRecord.FormattedMessage.set -> void +OpenTelemetry.Logs.LogRecord.LogLevel.get -> Microsoft.Extensions.Logging.LogLevel +OpenTelemetry.Logs.LogRecord.SpanId.get -> System.Diagnostics.ActivitySpanId +OpenTelemetry.Logs.LogRecord.State.get -> object? +OpenTelemetry.Logs.LogRecord.State.set -> void +OpenTelemetry.Logs.LogRecord.StateValues.get -> System.Collections.Generic.IReadOnlyList>? +OpenTelemetry.Logs.LogRecord.StateValues.set -> void +OpenTelemetry.Logs.LogRecord.Timestamp.get -> System.DateTime +OpenTelemetry.Logs.LogRecord.TraceFlags.get -> System.Diagnostics.ActivityTraceFlags +OpenTelemetry.Logs.LogRecord.TraceId.get -> System.Diagnostics.ActivityTraceId +OpenTelemetry.Logs.LogRecord.TraceState.get -> string? +OpenTelemetry.Logs.LogRecordScope +OpenTelemetry.Logs.LogRecordScope.Enumerator +OpenTelemetry.Logs.LogRecordScope.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair +OpenTelemetry.Logs.LogRecordScope.Enumerator.Dispose() -> void +OpenTelemetry.Logs.LogRecordScope.Enumerator.Enumerator() -> void +OpenTelemetry.Logs.LogRecordScope.Enumerator.Enumerator(object? scope) -> void +OpenTelemetry.Logs.LogRecordScope.Enumerator.MoveNext() -> bool +OpenTelemetry.Logs.LogRecordScope.Enumerator.Reset() -> void +OpenTelemetry.Logs.LogRecordScope.GetEnumerator() -> OpenTelemetry.Logs.LogRecordScope.Enumerator +OpenTelemetry.Logs.LogRecordScope.LogRecordScope() -> void +OpenTelemetry.Logs.LogRecordScope.Scope.get -> object? +OpenTelemetry.Logs.OpenTelemetryLoggerOptions +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeFormattedMessage.get -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeFormattedMessage.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.get -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.OpenTelemetryLoggerOptions() -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.CreateLogger(string! categoryName) -> Microsoft.Extensions.Logging.ILogger! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options) -> void +OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.AggregationTemporality.Cumulative = 1 -> OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.AggregationTemporality.Delta = 2 -> OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.BaseExportingMetricReader +OpenTelemetry.Metrics.BaseExportingMetricReader.SupportedExportModes.get -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration +OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.ExplicitBucketHistogramConfiguration() -> void +OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExportModes.Pull = 2 -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExportModes.Push = 1 -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExportModesAttribute +OpenTelemetry.Metrics.ExportModesAttribute.ExportModesAttribute(OpenTelemetry.Metrics.ExportModes supported) -> void +OpenTelemetry.Metrics.ExportModesAttribute.Supported.get -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.HistogramBucket +OpenTelemetry.Metrics.HistogramBucket.BucketCount.get -> long +OpenTelemetry.Metrics.HistogramBucket.ExplicitBound.get -> double +OpenTelemetry.Metrics.HistogramBucket.HistogramBucket() -> void +OpenTelemetry.Metrics.HistogramBuckets +OpenTelemetry.Metrics.HistogramBuckets.Enumerator +OpenTelemetry.Metrics.HistogramBuckets.Enumerator.Current.get -> OpenTelemetry.Metrics.HistogramBucket +OpenTelemetry.Metrics.HistogramBuckets.Enumerator.Enumerator() -> void +OpenTelemetry.Metrics.HistogramBuckets.Enumerator.MoveNext() -> bool +OpenTelemetry.Metrics.HistogramBuckets.GetEnumerator() -> OpenTelemetry.Metrics.HistogramBuckets.Enumerator +OpenTelemetry.Metrics.IPullMetricExporter +OpenTelemetry.Metrics.MeterProviderBuilderBase +OpenTelemetry.Metrics.MeterProviderBuilderBase.MeterProviderBuilderBase() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +OpenTelemetry.Metrics.MeterProviderExtensions +OpenTelemetry.Metrics.Metric +OpenTelemetry.Metrics.Metric.GetMetricPoints() -> OpenTelemetry.Metrics.MetricPointsAccessor +OpenTelemetry.Metrics.Metric.MetricType.get -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.Metric.Temporality.get -> OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.MetricPoint +OpenTelemetry.Metrics.MetricPoint.EndTime.get -> System.DateTimeOffset +OpenTelemetry.Metrics.MetricPoint.GetGaugeLastValueDouble() -> double +OpenTelemetry.Metrics.MetricPoint.GetGaugeLastValueLong() -> long +OpenTelemetry.Metrics.MetricPoint.GetHistogramCount() -> long +OpenTelemetry.Metrics.MetricPoint.GetHistogramSum() -> double +OpenTelemetry.Metrics.MetricPoint.GetSumDouble() -> double +OpenTelemetry.Metrics.MetricPoint.GetSumLong() -> long +OpenTelemetry.Metrics.MetricPoint.MetricPoint() -> void +OpenTelemetry.Metrics.MetricPoint.StartTime.get -> System.DateTimeOffset +OpenTelemetry.Metrics.MetricPoint.Tags.get -> OpenTelemetry.ReadOnlyTagCollection +OpenTelemetry.Metrics.MetricPointsAccessor +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator.Current.get -> OpenTelemetry.Metrics.MetricPoint +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator.Enumerator() -> void +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator.MoveNext() -> bool +OpenTelemetry.Metrics.MetricPointsAccessor.GetEnumerator() -> OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator +OpenTelemetry.Metrics.MetricPointsAccessor.MetricPointsAccessor() -> void +OpenTelemetry.Metrics.MetricReader +OpenTelemetry.Metrics.MetricReader.Collect(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Metrics.MetricReader.Dispose() -> void +OpenTelemetry.Metrics.MetricReader.MetricReader() -> void +OpenTelemetry.Metrics.MetricReader.Shutdown(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Metrics.MetricReader.TemporalityPreference.get -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReader.TemporalityPreference.set -> void +OpenTelemetry.Metrics.MetricReaderOptions +OpenTelemetry.Metrics.MetricReaderOptions.MetricReaderOptions() -> void +OpenTelemetry.Metrics.MetricReaderOptions.TemporalityPreference.get -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReaderOptions.TemporalityPreference.set -> void +OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReaderTemporalityPreference.Cumulative = 1 -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReaderTemporalityPreference.Delta = 2 -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricStreamConfiguration +OpenTelemetry.Metrics.MetricStreamConfiguration.MetricStreamConfiguration() -> void +OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.DoubleGauge = 45 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.DoubleSum = 29 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.Histogram = 64 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.LongGauge = 42 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.LongSum = 26 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricTypeExtensions +OpenTelemetry.Metrics.PeriodicExportingMetricReader +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds.get -> int? +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds.set -> void +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds.get -> int? +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds.set -> void +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.PeriodicExportingMetricReaderOptions() -> void +OpenTelemetry.ProviderExtensions +OpenTelemetry.ReadOnlyTagCollection +OpenTelemetry.ReadOnlyTagCollection.Count.get -> int +OpenTelemetry.ReadOnlyTagCollection.Enumerator +OpenTelemetry.ReadOnlyTagCollection.Enumerator.Enumerator() -> void +OpenTelemetry.ReadOnlyTagCollection.Enumerator.MoveNext() -> bool +OpenTelemetry.ReadOnlyTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyTagCollection.Enumerator +OpenTelemetry.ReadOnlyTagCollection.ReadOnlyTagCollection() -> void +OpenTelemetry.Resources.IResourceDetector +OpenTelemetry.Resources.Resource +OpenTelemetry.Resources.ResourceBuilder +OpenTelemetry.Resources.ResourceBuilderExtensions +OpenTelemetry.Sdk +OpenTelemetry.SimpleActivityExportProcessor +OpenTelemetry.SimpleLogRecordExportProcessor +OpenTelemetry.SimpleLogRecordExportProcessor.SimpleLogRecordExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +OpenTelemetry.SuppressInstrumentationScope +OpenTelemetry.SuppressInstrumentationScope.Dispose() -> void +OpenTelemetry.Trace.AlwaysOffSampler +OpenTelemetry.Trace.AlwaysOffSampler.AlwaysOffSampler() -> void +OpenTelemetry.Trace.AlwaysOnSampler +OpenTelemetry.Trace.AlwaysOnSampler.AlwaysOnSampler() -> void +OpenTelemetry.Trace.BatchExportActivityProcessorOptions +OpenTelemetry.Trace.BatchExportActivityProcessorOptions.BatchExportActivityProcessorOptions() -> void +OpenTelemetry.Trace.ParentBasedSampler +OpenTelemetry.Trace.Sampler +OpenTelemetry.Trace.Sampler.Sampler() -> void +OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingDecision.Drop = 0 -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingDecision.RecordAndSample = 2 -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingDecision.RecordOnly = 1 -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingParameters +OpenTelemetry.Trace.SamplingParameters.Kind.get -> System.Diagnostics.ActivityKind +OpenTelemetry.Trace.SamplingParameters.ParentContext.get -> System.Diagnostics.ActivityContext +OpenTelemetry.Trace.SamplingParameters.SamplingParameters() -> void +OpenTelemetry.Trace.SamplingParameters.TraceId.get -> System.Diagnostics.ActivityTraceId +OpenTelemetry.Trace.SamplingResult +OpenTelemetry.Trace.SamplingResult.Decision.get -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingResult.Equals(OpenTelemetry.Trace.SamplingResult other) -> bool +OpenTelemetry.Trace.SamplingResult.SamplingResult() -> void +OpenTelemetry.Trace.SamplingResult.SamplingResult(bool isSampled) -> void +OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision) -> void +OpenTelemetry.Trace.TraceIdRatioBasedSampler +OpenTelemetry.Trace.TraceIdRatioBasedSampler.TraceIdRatioBasedSampler(double probability) -> void +OpenTelemetry.Trace.TracerProviderBuilderBase +OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +OpenTelemetry.Trace.TracerProviderExtensions +override OpenTelemetry.BaseExportProcessor.Dispose(bool disposing) -> void +override OpenTelemetry.BaseExportProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +override OpenTelemetry.BaseExportProcessor.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.BatchExportProcessor.Dispose(bool disposing) -> void +override OpenTelemetry.BatchExportProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +override OpenTelemetry.BatchExportProcessor.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.BatchLogRecordExportProcessor.OnEnd(OpenTelemetry.Logs.LogRecord! data) -> void +override OpenTelemetry.CompositeProcessor.Dispose(bool disposing) -> void +override OpenTelemetry.CompositeProcessor.OnEnd(T data) -> void +override OpenTelemetry.CompositeProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +override OpenTelemetry.CompositeProcessor.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.CompositeProcessor.OnStart(T data) -> void +override OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Dispose(bool disposing) -> void +override OpenTelemetry.Metrics.BaseExportingMetricReader.Dispose(bool disposing) -> void +override OpenTelemetry.Metrics.BaseExportingMetricReader.OnCollect(int timeoutMilliseconds) -> bool +override OpenTelemetry.Metrics.BaseExportingMetricReader.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.Metrics.PeriodicExportingMetricReader.Dispose(bool disposing) -> void +override OpenTelemetry.Metrics.PeriodicExportingMetricReader.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.Trace.AlwaysOffSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +override OpenTelemetry.Trace.AlwaysOnSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +override OpenTelemetry.Trace.ParentBasedSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +override OpenTelemetry.Trace.SamplingResult.GetHashCode() -> int +override OpenTelemetry.Trace.TraceIdRatioBasedSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Metrics.MetricTypeExtensions.IsDouble(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsGauge(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsHistogram(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsLong(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsSum(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Sdk.SuppressInstrumentation.get -> bool +static OpenTelemetry.SuppressInstrumentationScope.Enter() -> int +static OpenTelemetry.Trace.SamplingResult.operator !=(OpenTelemetry.Trace.SamplingResult decision1, OpenTelemetry.Trace.SamplingResult decision2) -> bool +static OpenTelemetry.Trace.SamplingResult.operator ==(OpenTelemetry.Trace.SamplingResult decision1, OpenTelemetry.Trace.SamplingResult decision2) -> bool +virtual OpenTelemetry.BaseExporter.Dispose(bool disposing) -> void +virtual OpenTelemetry.BaseExporter.OnForceFlush(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseExporter.OnShutdown(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseProcessor.Dispose(bool disposing) -> void +virtual OpenTelemetry.BaseProcessor.OnEnd(T data) -> void +virtual OpenTelemetry.BaseProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseProcessor.OnShutdown(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseProcessor.OnStart(T data) -> void +virtual OpenTelemetry.Metrics.MetricReader.Dispose(bool disposing) -> void +virtual OpenTelemetry.Metrics.MetricReader.OnCollect(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.Metrics.MetricReader.OnShutdown(int timeoutMilliseconds) -> bool diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 00000000000..43156ee3c3a --- /dev/null +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Logs.LogRecord.CategoryName.set -> void +OpenTelemetry.Logs.LogRecord.EventId.set -> void +OpenTelemetry.Logs.LogRecord.Exception.set -> void +OpenTelemetry.Logs.LogRecord.LogLevel.set -> void +OpenTelemetry.Logs.LogRecord.SpanId.set -> void +OpenTelemetry.Logs.LogRecord.Timestamp.set -> void +OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void +OpenTelemetry.Logs.LogRecord.TraceId.set -> void +OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 56774a7fc4d..afa4f5a68a7 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1,21 +1,21 @@ #nullable enable -~abstract OpenTelemetry.BaseExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -~abstract OpenTelemetry.BaseExportProcessor.OnExport(T data) -> void -~OpenTelemetry.BaseExporter -~OpenTelemetry.BaseExporter.ParentProvider.get -> OpenTelemetry.BaseProvider -~OpenTelemetry.BaseExportProcessor -~OpenTelemetry.BaseExportProcessor.BaseExportProcessor(OpenTelemetry.BaseExporter exporter) -> void -~OpenTelemetry.BaseProcessor.ParentProvider.get -> OpenTelemetry.BaseProvider -~OpenTelemetry.Batch -~OpenTelemetry.Batch.Batch(T[] items, int count) -> void -~OpenTelemetry.Batch.Enumerator.Current.get -> T +abstract OpenTelemetry.BaseExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +abstract OpenTelemetry.BaseExportProcessor.OnExport(T! data) -> void +OpenTelemetry.BaseExporter +OpenTelemetry.BaseExporter.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.BaseExportProcessor +OpenTelemetry.BaseExportProcessor.BaseExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +OpenTelemetry.BaseProcessor.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.Batch +OpenTelemetry.Batch.Batch(T![]! items, int count) -> void +OpenTelemetry.Batch.Enumerator.Current.get -> T! ~OpenTelemetry.Batch.GetEnumerator() -> OpenTelemetry.Batch.Enumerator ~OpenTelemetry.BatchActivityExportProcessor.BatchActivityExportProcessor(OpenTelemetry.BaseExporter exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void -~OpenTelemetry.BatchExportProcessor -~OpenTelemetry.BatchExportProcessor.BatchExportProcessor(OpenTelemetry.BaseExporter exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +OpenTelemetry.BatchExportProcessor +OpenTelemetry.BatchExportProcessor.BatchExportProcessor(OpenTelemetry.BaseExporter! exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void ~OpenTelemetry.BatchExportProcessorOptions -~OpenTelemetry.CompositeProcessor.AddProcessor(OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.CompositeProcessor -~OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generic.IEnumerable> processors) -> void +OpenTelemetry.CompositeProcessor.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.CompositeProcessor! +OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generic.IEnumerable!>! processors) -> void ~OpenTelemetry.Metrics.BaseExportingMetricReader.BaseExportingMetricReader(OpenTelemetry.BaseExporter exporter) -> void ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.get -> double[] ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void @@ -46,8 +46,8 @@ ~OpenTelemetry.Resources.ResourceBuilder.Build() -> OpenTelemetry.Resources.Resource ~OpenTelemetry.Resources.ResourceBuilder.Clear() -> OpenTelemetry.Resources.ResourceBuilder ~OpenTelemetry.SimpleActivityExportProcessor.SimpleActivityExportProcessor(OpenTelemetry.BaseExporter exporter) -> void -~OpenTelemetry.SimpleExportProcessor -~OpenTelemetry.SimpleExportProcessor.SimpleExportProcessor(OpenTelemetry.BaseExporter exporter) -> void +OpenTelemetry.SimpleExportProcessor +OpenTelemetry.SimpleExportProcessor.SimpleExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void ~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler) -> void ~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void ~OpenTelemetry.Trace.Sampler.Description.get -> string @@ -60,19 +60,19 @@ ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes) -> void ~OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder ~OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider -~override OpenTelemetry.BaseExportProcessor.OnEnd(T data) -> void +override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void -~override OpenTelemetry.BatchExportProcessor.OnExport(T data) -> void +override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder ~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void -~override OpenTelemetry.SimpleExportProcessor.OnExport(T data) -> void +override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool ~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder ~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddLegacySource(string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder ~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder -~override sealed OpenTelemetry.BaseExportProcessor.OnStart(T data) -> void -~readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter +override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void +readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter ~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder ~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder @@ -145,7 +145,7 @@ OpenTelemetry.ExportResult OpenTelemetry.ExportResult.Failure = 1 -> OpenTelemetry.ExportResult OpenTelemetry.ExportResult.Success = 0 -> OpenTelemetry.ExportResult OpenTelemetry.Logs.LogRecord -OpenTelemetry.Logs.LogRecord.CategoryName.get -> string! +OpenTelemetry.Logs.LogRecord.CategoryName.get -> string? OpenTelemetry.Logs.LogRecord.EventId.get -> Microsoft.Extensions.Logging.EventId OpenTelemetry.Logs.LogRecord.Exception.get -> System.Exception? OpenTelemetry.Logs.LogRecord.ForEachScope(System.Action! callback, TState state) -> void diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..ecaf006aa47 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Logs.LogRecord.CategoryName.set -> void +OpenTelemetry.Logs.LogRecord.EventId.set -> void +OpenTelemetry.Logs.LogRecord.Exception.set -> void +OpenTelemetry.Logs.LogRecord.LogLevel.set -> void +OpenTelemetry.Logs.LogRecord.SpanId.set -> void +OpenTelemetry.Logs.LogRecord.Timestamp.set -> void +OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void +OpenTelemetry.Logs.LogRecord.TraceId.set -> void +OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt new file mode 100644 index 00000000000..afa4f5a68a7 --- /dev/null +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt @@ -0,0 +1,359 @@ +#nullable enable +abstract OpenTelemetry.BaseExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +abstract OpenTelemetry.BaseExportProcessor.OnExport(T! data) -> void +OpenTelemetry.BaseExporter +OpenTelemetry.BaseExporter.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.BaseExportProcessor +OpenTelemetry.BaseExportProcessor.BaseExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +OpenTelemetry.BaseProcessor.ParentProvider.get -> OpenTelemetry.BaseProvider? +OpenTelemetry.Batch +OpenTelemetry.Batch.Batch(T![]! items, int count) -> void +OpenTelemetry.Batch.Enumerator.Current.get -> T! +~OpenTelemetry.Batch.GetEnumerator() -> OpenTelemetry.Batch.Enumerator +~OpenTelemetry.BatchActivityExportProcessor.BatchActivityExportProcessor(OpenTelemetry.BaseExporter exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +OpenTelemetry.BatchExportProcessor +OpenTelemetry.BatchExportProcessor.BatchExportProcessor(OpenTelemetry.BaseExporter! exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +~OpenTelemetry.BatchExportProcessorOptions +OpenTelemetry.CompositeProcessor.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.CompositeProcessor! +OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generic.IEnumerable!>! processors) -> void +~OpenTelemetry.Metrics.BaseExportingMetricReader.BaseExportingMetricReader(OpenTelemetry.BaseExporter exporter) -> void +~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.get -> double[] +~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void +~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func +~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void +~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +~OpenTelemetry.Metrics.Metric.Description.get -> string +~OpenTelemetry.Metrics.Metric.MeterName.get -> string +~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string +~OpenTelemetry.Metrics.Metric.Name.get -> string +~OpenTelemetry.Metrics.Metric.Unit.get -> string +~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets +~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions +~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string +~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void +~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string +~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.set -> void +~OpenTelemetry.Metrics.MetricStreamConfiguration.TagKeys.get -> string[] +~OpenTelemetry.Metrics.MetricStreamConfiguration.TagKeys.set -> void +~OpenTelemetry.Metrics.PeriodicExportingMetricReader.PeriodicExportingMetricReader(OpenTelemetry.BaseExporter exporter, int exportIntervalMilliseconds = 60000, int exportTimeoutMilliseconds = 30000) -> void +~OpenTelemetry.ReadOnlyTagCollection.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair +~OpenTelemetry.Resources.IResourceDetector.Detect() -> OpenTelemetry.Resources.Resource +~OpenTelemetry.Resources.Resource.Attributes.get -> System.Collections.Generic.IEnumerable> +~OpenTelemetry.Resources.Resource.Merge(OpenTelemetry.Resources.Resource other) -> OpenTelemetry.Resources.Resource +~OpenTelemetry.Resources.Resource.Resource(System.Collections.Generic.IEnumerable> attributes) -> void +~OpenTelemetry.Resources.ResourceBuilder.AddDetector(OpenTelemetry.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder +~OpenTelemetry.Resources.ResourceBuilder.Build() -> OpenTelemetry.Resources.Resource +~OpenTelemetry.Resources.ResourceBuilder.Clear() -> OpenTelemetry.Resources.ResourceBuilder +~OpenTelemetry.SimpleActivityExportProcessor.SimpleActivityExportProcessor(OpenTelemetry.BaseExporter exporter) -> void +OpenTelemetry.SimpleExportProcessor +OpenTelemetry.SimpleExportProcessor.SimpleExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler) -> void +~OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void +~OpenTelemetry.Trace.Sampler.Description.get -> string +~OpenTelemetry.Trace.Sampler.Description.set -> void +~OpenTelemetry.Trace.SamplingParameters.Links.get -> System.Collections.Generic.IEnumerable +~OpenTelemetry.Trace.SamplingParameters.Name.get -> string +~OpenTelemetry.Trace.SamplingParameters.SamplingParameters(System.Diagnostics.ActivityContext parentContext, System.Diagnostics.ActivityTraceId traceId, string name, System.Diagnostics.ActivityKind kind, System.Collections.Generic.IEnumerable> tags = null, System.Collections.Generic.IEnumerable links = null) -> void +~OpenTelemetry.Trace.SamplingParameters.Tags.get -> System.Collections.Generic.IEnumerable> +~OpenTelemetry.Trace.SamplingResult.Attributes.get -> System.Collections.Generic.IEnumerable> +~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes) -> void +~OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +~OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider +override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void +~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void +override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void +override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void +~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool +~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddLegacySource(string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder +~override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder +override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void +readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! +~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool +~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool +~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration +~static OpenTelemetry.ProviderExtensions.GetDefaultResource(this OpenTelemetry.BaseProvider baseProvider) -> OpenTelemetry.Resources.Resource +~static OpenTelemetry.ProviderExtensions.GetResource(this OpenTelemetry.BaseProvider baseProvider) -> OpenTelemetry.Resources.Resource +~static OpenTelemetry.Resources.Resource.Empty.get -> OpenTelemetry.Resources.Resource +~static OpenTelemetry.Resources.ResourceBuilder.CreateDefault() -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilder.CreateEmpty() -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddAttributes(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, System.Collections.Generic.IEnumerable> attributes) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddEnvironmentVariableDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddService(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, string serviceName, string serviceNamespace = null, string serviceVersion = null, bool autoGenerateServiceInstanceId = true, string serviceInstanceId = null) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddTelemetrySdk(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder +~static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator textMapPropagator) -> void +~static OpenTelemetry.SuppressInstrumentationScope.Begin(bool value = true) -> System.IDisposable +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProvider +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetErrorStatusOnException(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, bool enabled = true) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetSampler(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.Trace.Sampler sampler) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Trace.TracerProviderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProvider provider, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProvider +~static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool +~static OpenTelemetry.Trace.TracerProviderExtensions.Shutdown(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool +abstract OpenTelemetry.Trace.Sampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions +OpenTelemetry.BaseExporter.BaseExporter() -> void +OpenTelemetry.BaseExporter.Dispose() -> void +OpenTelemetry.BaseExporter.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.BaseExporter.Shutdown(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.BaseProcessor +OpenTelemetry.BaseProcessor.BaseProcessor() -> void +OpenTelemetry.BaseProcessor.Dispose() -> void +OpenTelemetry.BaseProcessor.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.BaseProcessor.Shutdown(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Batch.Batch() -> void +OpenTelemetry.Batch.Count.get -> long +OpenTelemetry.Batch.Dispose() -> void +OpenTelemetry.Batch.Enumerator +OpenTelemetry.Batch.Enumerator.Dispose() -> void +OpenTelemetry.Batch.Enumerator.Enumerator() -> void +OpenTelemetry.Batch.Enumerator.MoveNext() -> bool +OpenTelemetry.Batch.Enumerator.Reset() -> void +OpenTelemetry.BatchActivityExportProcessor +OpenTelemetry.BatchExportProcessorOptions.BatchExportProcessorOptions() -> void +OpenTelemetry.BatchExportProcessorOptions.ExporterTimeoutMilliseconds.get -> int +OpenTelemetry.BatchExportProcessorOptions.ExporterTimeoutMilliseconds.set -> void +OpenTelemetry.BatchExportProcessorOptions.MaxExportBatchSize.get -> int +OpenTelemetry.BatchExportProcessorOptions.MaxExportBatchSize.set -> void +OpenTelemetry.BatchExportProcessorOptions.MaxQueueSize.get -> int +OpenTelemetry.BatchExportProcessorOptions.MaxQueueSize.set -> void +OpenTelemetry.BatchExportProcessorOptions.ScheduledDelayMilliseconds.get -> int +OpenTelemetry.BatchExportProcessorOptions.ScheduledDelayMilliseconds.set -> void +OpenTelemetry.BatchLogRecordExportProcessor +OpenTelemetry.BatchLogRecordExportProcessor.BatchLogRecordExportProcessor(OpenTelemetry.BaseExporter! exporter, int maxQueueSize = 2048, int scheduledDelayMilliseconds = 5000, int exporterTimeoutMilliseconds = 30000, int maxExportBatchSize = 512) -> void +OpenTelemetry.CompositeProcessor +OpenTelemetry.ExportProcessorType +OpenTelemetry.ExportProcessorType.Batch = 1 -> OpenTelemetry.ExportProcessorType +OpenTelemetry.ExportProcessorType.Simple = 0 -> OpenTelemetry.ExportProcessorType +OpenTelemetry.ExportResult +OpenTelemetry.ExportResult.Failure = 1 -> OpenTelemetry.ExportResult +OpenTelemetry.ExportResult.Success = 0 -> OpenTelemetry.ExportResult +OpenTelemetry.Logs.LogRecord +OpenTelemetry.Logs.LogRecord.CategoryName.get -> string? +OpenTelemetry.Logs.LogRecord.EventId.get -> Microsoft.Extensions.Logging.EventId +OpenTelemetry.Logs.LogRecord.Exception.get -> System.Exception? +OpenTelemetry.Logs.LogRecord.ForEachScope(System.Action! callback, TState state) -> void +OpenTelemetry.Logs.LogRecord.FormattedMessage.get -> string? +OpenTelemetry.Logs.LogRecord.FormattedMessage.set -> void +OpenTelemetry.Logs.LogRecord.LogLevel.get -> Microsoft.Extensions.Logging.LogLevel +OpenTelemetry.Logs.LogRecord.SpanId.get -> System.Diagnostics.ActivitySpanId +OpenTelemetry.Logs.LogRecord.State.get -> object? +OpenTelemetry.Logs.LogRecord.State.set -> void +OpenTelemetry.Logs.LogRecord.StateValues.get -> System.Collections.Generic.IReadOnlyList>? +OpenTelemetry.Logs.LogRecord.StateValues.set -> void +OpenTelemetry.Logs.LogRecord.Timestamp.get -> System.DateTime +OpenTelemetry.Logs.LogRecord.TraceFlags.get -> System.Diagnostics.ActivityTraceFlags +OpenTelemetry.Logs.LogRecord.TraceId.get -> System.Diagnostics.ActivityTraceId +OpenTelemetry.Logs.LogRecord.TraceState.get -> string? +OpenTelemetry.Logs.LogRecordScope +OpenTelemetry.Logs.LogRecordScope.Enumerator +OpenTelemetry.Logs.LogRecordScope.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair +OpenTelemetry.Logs.LogRecordScope.Enumerator.Dispose() -> void +OpenTelemetry.Logs.LogRecordScope.Enumerator.Enumerator() -> void +OpenTelemetry.Logs.LogRecordScope.Enumerator.Enumerator(object? scope) -> void +OpenTelemetry.Logs.LogRecordScope.Enumerator.MoveNext() -> bool +OpenTelemetry.Logs.LogRecordScope.Enumerator.Reset() -> void +OpenTelemetry.Logs.LogRecordScope.GetEnumerator() -> OpenTelemetry.Logs.LogRecordScope.Enumerator +OpenTelemetry.Logs.LogRecordScope.LogRecordScope() -> void +OpenTelemetry.Logs.LogRecordScope.Scope.get -> object? +OpenTelemetry.Logs.OpenTelemetryLoggerOptions +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeFormattedMessage.get -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeFormattedMessage.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.get -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.OpenTelemetryLoggerOptions() -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.CreateLogger(string! categoryName) -> Microsoft.Extensions.Logging.ILogger! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options) -> void +OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.AggregationTemporality.Cumulative = 1 -> OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.AggregationTemporality.Delta = 2 -> OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.BaseExportingMetricReader +OpenTelemetry.Metrics.BaseExportingMetricReader.SupportedExportModes.get -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration +OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.ExplicitBucketHistogramConfiguration() -> void +OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExportModes.Pull = 2 -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExportModes.Push = 1 -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.ExportModesAttribute +OpenTelemetry.Metrics.ExportModesAttribute.ExportModesAttribute(OpenTelemetry.Metrics.ExportModes supported) -> void +OpenTelemetry.Metrics.ExportModesAttribute.Supported.get -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.HistogramBucket +OpenTelemetry.Metrics.HistogramBucket.BucketCount.get -> long +OpenTelemetry.Metrics.HistogramBucket.ExplicitBound.get -> double +OpenTelemetry.Metrics.HistogramBucket.HistogramBucket() -> void +OpenTelemetry.Metrics.HistogramBuckets +OpenTelemetry.Metrics.HistogramBuckets.Enumerator +OpenTelemetry.Metrics.HistogramBuckets.Enumerator.Current.get -> OpenTelemetry.Metrics.HistogramBucket +OpenTelemetry.Metrics.HistogramBuckets.Enumerator.Enumerator() -> void +OpenTelemetry.Metrics.HistogramBuckets.Enumerator.MoveNext() -> bool +OpenTelemetry.Metrics.HistogramBuckets.GetEnumerator() -> OpenTelemetry.Metrics.HistogramBuckets.Enumerator +OpenTelemetry.Metrics.IPullMetricExporter +OpenTelemetry.Metrics.MeterProviderBuilderBase +OpenTelemetry.Metrics.MeterProviderBuilderBase.MeterProviderBuilderBase() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +OpenTelemetry.Metrics.MeterProviderExtensions +OpenTelemetry.Metrics.Metric +OpenTelemetry.Metrics.Metric.GetMetricPoints() -> OpenTelemetry.Metrics.MetricPointsAccessor +OpenTelemetry.Metrics.Metric.MetricType.get -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.Metric.Temporality.get -> OpenTelemetry.Metrics.AggregationTemporality +OpenTelemetry.Metrics.MetricPoint +OpenTelemetry.Metrics.MetricPoint.EndTime.get -> System.DateTimeOffset +OpenTelemetry.Metrics.MetricPoint.GetGaugeLastValueDouble() -> double +OpenTelemetry.Metrics.MetricPoint.GetGaugeLastValueLong() -> long +OpenTelemetry.Metrics.MetricPoint.GetHistogramCount() -> long +OpenTelemetry.Metrics.MetricPoint.GetHistogramSum() -> double +OpenTelemetry.Metrics.MetricPoint.GetSumDouble() -> double +OpenTelemetry.Metrics.MetricPoint.GetSumLong() -> long +OpenTelemetry.Metrics.MetricPoint.MetricPoint() -> void +OpenTelemetry.Metrics.MetricPoint.StartTime.get -> System.DateTimeOffset +OpenTelemetry.Metrics.MetricPoint.Tags.get -> OpenTelemetry.ReadOnlyTagCollection +OpenTelemetry.Metrics.MetricPointsAccessor +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator.Current.get -> OpenTelemetry.Metrics.MetricPoint +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator.Enumerator() -> void +OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator.MoveNext() -> bool +OpenTelemetry.Metrics.MetricPointsAccessor.GetEnumerator() -> OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator +OpenTelemetry.Metrics.MetricPointsAccessor.MetricPointsAccessor() -> void +OpenTelemetry.Metrics.MetricReader +OpenTelemetry.Metrics.MetricReader.Collect(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Metrics.MetricReader.Dispose() -> void +OpenTelemetry.Metrics.MetricReader.MetricReader() -> void +OpenTelemetry.Metrics.MetricReader.Shutdown(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Metrics.MetricReader.TemporalityPreference.get -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReader.TemporalityPreference.set -> void +OpenTelemetry.Metrics.MetricReaderOptions +OpenTelemetry.Metrics.MetricReaderOptions.MetricReaderOptions() -> void +OpenTelemetry.Metrics.MetricReaderOptions.TemporalityPreference.get -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReaderOptions.TemporalityPreference.set -> void +OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReaderTemporalityPreference.Cumulative = 1 -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricReaderTemporalityPreference.Delta = 2 -> OpenTelemetry.Metrics.MetricReaderTemporalityPreference +OpenTelemetry.Metrics.MetricStreamConfiguration +OpenTelemetry.Metrics.MetricStreamConfiguration.MetricStreamConfiguration() -> void +OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.DoubleGauge = 45 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.DoubleSum = 29 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.Histogram = 64 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.LongGauge = 42 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricType.LongSum = 26 -> OpenTelemetry.Metrics.MetricType +OpenTelemetry.Metrics.MetricTypeExtensions +OpenTelemetry.Metrics.PeriodicExportingMetricReader +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds.get -> int? +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds.set -> void +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds.get -> int? +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds.set -> void +OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.PeriodicExportingMetricReaderOptions() -> void +OpenTelemetry.ProviderExtensions +OpenTelemetry.ReadOnlyTagCollection +OpenTelemetry.ReadOnlyTagCollection.Count.get -> int +OpenTelemetry.ReadOnlyTagCollection.Enumerator +OpenTelemetry.ReadOnlyTagCollection.Enumerator.Enumerator() -> void +OpenTelemetry.ReadOnlyTagCollection.Enumerator.MoveNext() -> bool +OpenTelemetry.ReadOnlyTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyTagCollection.Enumerator +OpenTelemetry.ReadOnlyTagCollection.ReadOnlyTagCollection() -> void +OpenTelemetry.Resources.IResourceDetector +OpenTelemetry.Resources.Resource +OpenTelemetry.Resources.ResourceBuilder +OpenTelemetry.Resources.ResourceBuilderExtensions +OpenTelemetry.Sdk +OpenTelemetry.SimpleActivityExportProcessor +OpenTelemetry.SimpleLogRecordExportProcessor +OpenTelemetry.SimpleLogRecordExportProcessor.SimpleLogRecordExportProcessor(OpenTelemetry.BaseExporter! exporter) -> void +OpenTelemetry.SuppressInstrumentationScope +OpenTelemetry.SuppressInstrumentationScope.Dispose() -> void +OpenTelemetry.Trace.AlwaysOffSampler +OpenTelemetry.Trace.AlwaysOffSampler.AlwaysOffSampler() -> void +OpenTelemetry.Trace.AlwaysOnSampler +OpenTelemetry.Trace.AlwaysOnSampler.AlwaysOnSampler() -> void +OpenTelemetry.Trace.BatchExportActivityProcessorOptions +OpenTelemetry.Trace.BatchExportActivityProcessorOptions.BatchExportActivityProcessorOptions() -> void +OpenTelemetry.Trace.ParentBasedSampler +OpenTelemetry.Trace.Sampler +OpenTelemetry.Trace.Sampler.Sampler() -> void +OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingDecision.Drop = 0 -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingDecision.RecordAndSample = 2 -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingDecision.RecordOnly = 1 -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingParameters +OpenTelemetry.Trace.SamplingParameters.Kind.get -> System.Diagnostics.ActivityKind +OpenTelemetry.Trace.SamplingParameters.ParentContext.get -> System.Diagnostics.ActivityContext +OpenTelemetry.Trace.SamplingParameters.SamplingParameters() -> void +OpenTelemetry.Trace.SamplingParameters.TraceId.get -> System.Diagnostics.ActivityTraceId +OpenTelemetry.Trace.SamplingResult +OpenTelemetry.Trace.SamplingResult.Decision.get -> OpenTelemetry.Trace.SamplingDecision +OpenTelemetry.Trace.SamplingResult.Equals(OpenTelemetry.Trace.SamplingResult other) -> bool +OpenTelemetry.Trace.SamplingResult.SamplingResult() -> void +OpenTelemetry.Trace.SamplingResult.SamplingResult(bool isSampled) -> void +OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision) -> void +OpenTelemetry.Trace.TraceIdRatioBasedSampler +OpenTelemetry.Trace.TraceIdRatioBasedSampler.TraceIdRatioBasedSampler(double probability) -> void +OpenTelemetry.Trace.TracerProviderBuilderBase +OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +OpenTelemetry.Trace.TracerProviderExtensions +override OpenTelemetry.BaseExportProcessor.Dispose(bool disposing) -> void +override OpenTelemetry.BaseExportProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +override OpenTelemetry.BaseExportProcessor.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.BatchExportProcessor.Dispose(bool disposing) -> void +override OpenTelemetry.BatchExportProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +override OpenTelemetry.BatchExportProcessor.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.BatchLogRecordExportProcessor.OnEnd(OpenTelemetry.Logs.LogRecord! data) -> void +override OpenTelemetry.CompositeProcessor.Dispose(bool disposing) -> void +override OpenTelemetry.CompositeProcessor.OnEnd(T data) -> void +override OpenTelemetry.CompositeProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +override OpenTelemetry.CompositeProcessor.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.CompositeProcessor.OnStart(T data) -> void +override OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Dispose(bool disposing) -> void +override OpenTelemetry.Metrics.BaseExportingMetricReader.Dispose(bool disposing) -> void +override OpenTelemetry.Metrics.BaseExportingMetricReader.OnCollect(int timeoutMilliseconds) -> bool +override OpenTelemetry.Metrics.BaseExportingMetricReader.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.Metrics.PeriodicExportingMetricReader.Dispose(bool disposing) -> void +override OpenTelemetry.Metrics.PeriodicExportingMetricReader.OnShutdown(int timeoutMilliseconds) -> bool +override OpenTelemetry.Trace.AlwaysOffSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +override OpenTelemetry.Trace.AlwaysOnSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +override OpenTelemetry.Trace.ParentBasedSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +override OpenTelemetry.Trace.SamplingResult.GetHashCode() -> int +override OpenTelemetry.Trace.TraceIdRatioBasedSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Metrics.MetricTypeExtensions.IsDouble(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsGauge(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsHistogram(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsLong(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Metrics.MetricTypeExtensions.IsSum(this OpenTelemetry.Metrics.MetricType self) -> bool +static OpenTelemetry.Sdk.SuppressInstrumentation.get -> bool +static OpenTelemetry.SuppressInstrumentationScope.Enter() -> int +static OpenTelemetry.Trace.SamplingResult.operator !=(OpenTelemetry.Trace.SamplingResult decision1, OpenTelemetry.Trace.SamplingResult decision2) -> bool +static OpenTelemetry.Trace.SamplingResult.operator ==(OpenTelemetry.Trace.SamplingResult decision1, OpenTelemetry.Trace.SamplingResult decision2) -> bool +virtual OpenTelemetry.BaseExporter.Dispose(bool disposing) -> void +virtual OpenTelemetry.BaseExporter.OnForceFlush(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseExporter.OnShutdown(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseProcessor.Dispose(bool disposing) -> void +virtual OpenTelemetry.BaseProcessor.OnEnd(T data) -> void +virtual OpenTelemetry.BaseProcessor.OnForceFlush(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseProcessor.OnShutdown(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.BaseProcessor.OnStart(T data) -> void +virtual OpenTelemetry.Metrics.MetricReader.Dispose(bool disposing) -> void +virtual OpenTelemetry.Metrics.MetricReader.OnCollect(int timeoutMilliseconds) -> bool +virtual OpenTelemetry.Metrics.MetricReader.OnShutdown(int timeoutMilliseconds) -> bool diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt new file mode 100644 index 00000000000..43156ee3c3a --- /dev/null +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Logs.LogRecord.CategoryName.set -> void +OpenTelemetry.Logs.LogRecord.EventId.set -> void +OpenTelemetry.Logs.LogRecord.Exception.set -> void +OpenTelemetry.Logs.LogRecord.LogLevel.set -> void +OpenTelemetry.Logs.LogRecord.SpanId.set -> void +OpenTelemetry.Logs.LogRecord.Timestamp.set -> void +OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void +OpenTelemetry.Logs.LogRecord.TraceId.set -> void +OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void +~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry/BaseExportProcessor.cs b/src/OpenTelemetry/BaseExportProcessor.cs index 4bddbeff445..7b1b1bbfa06 100644 --- a/src/OpenTelemetry/BaseExportProcessor.cs +++ b/src/OpenTelemetry/BaseExportProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry/BaseExporter.cs b/src/OpenTelemetry/BaseExporter.cs index f188b07282c..cb1d70d84d0 100644 --- a/src/OpenTelemetry/BaseExporter.cs +++ b/src/OpenTelemetry/BaseExporter.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Threading; using OpenTelemetry.Internal; @@ -48,7 +50,7 @@ public abstract class BaseExporter : IDisposable /// /// Gets the parent . /// - public BaseProvider ParentProvider { get; internal set; } + public BaseProvider? ParentProvider { get; internal set; } /// /// Exports a batch of telemetry objects. diff --git a/src/OpenTelemetry/BaseProcessor.cs b/src/OpenTelemetry/BaseProcessor.cs index 4115b108ee6..02df50e39bf 100644 --- a/src/OpenTelemetry/BaseProcessor.cs +++ b/src/OpenTelemetry/BaseProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Threading; using OpenTelemetry.Internal; @@ -26,12 +28,21 @@ namespace OpenTelemetry /// The type of object to be processed. public abstract class BaseProcessor : IDisposable { + private readonly string typeName; private int shutdownCount; + /// + /// Initializes a new instance of the class. + /// + public BaseProcessor() + { + this.typeName = this.GetType().Name; + } + /// /// Gets the parent . /// - public BaseProvider ParentProvider { get; private set; } + public BaseProvider? ParentProvider { get; private set; } /// /// Called synchronously when a telemetry object is started. @@ -86,7 +97,11 @@ public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite) try { - return this.OnForceFlush(timeoutMilliseconds); + bool result = this.OnForceFlush(timeoutMilliseconds); + + OpenTelemetrySdkEventSource.Log.ProcessorForceFlushInvoked(this.typeName, result); + + return result; } catch (Exception ex) { diff --git a/src/OpenTelemetry/Batch.cs b/src/OpenTelemetry/Batch.cs index df54bb81131..b518e8c5d05 100644 --- a/src/OpenTelemetry/Batch.cs +++ b/src/OpenTelemetry/Batch.cs @@ -14,10 +14,13 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; namespace OpenTelemetry @@ -29,9 +32,9 @@ namespace OpenTelemetry public readonly struct Batch : IDisposable where T : class { - private readonly T item; - private readonly CircularBuffer circularBuffer; - private readonly T[] items; + private readonly T? item; + private readonly CircularBuffer? circularBuffer; + private readonly T[]? items; private readonly long targetCount; /// @@ -68,7 +71,7 @@ internal Batch(CircularBuffer circularBuffer, int maxSize) this.item = null; this.items = null; this.circularBuffer = circularBuffer; - this.Count = Math.Min(maxSize, circularBuffer.Count); + this.Count = Math.Min(maxSize, circularBuffer!.Count); this.targetCount = circularBuffer.RemovedCount + this.Count; } @@ -115,7 +118,7 @@ public struct Enumerator : IEnumerator { if (enumerator.targetCount >= 0) { - enumerator.Current = null; + enumerator.current = null; return false; } @@ -127,13 +130,13 @@ public struct Enumerator : IEnumerator { var circularBuffer = enumerator.circularBuffer; - if (circularBuffer.RemovedCount < enumerator.targetCount) + if (circularBuffer!.RemovedCount < enumerator.targetCount) { - enumerator.Current = circularBuffer.Read(); + enumerator.current = circularBuffer.Read(); return true; } - enumerator.Current = null; + enumerator.current = null; return false; }; @@ -143,23 +146,25 @@ public struct Enumerator : IEnumerator if (enumerator.itemIndex < enumerator.targetCount) { - enumerator.Current = items[enumerator.itemIndex++]; + enumerator.current = items![enumerator.itemIndex++]; return true; } - enumerator.Current = null; + enumerator.current = null; return false; }; - private readonly CircularBuffer circularBuffer; - private readonly T[] items; + private readonly CircularBuffer? circularBuffer; + private readonly T[]? items; private readonly BatchEnumeratorMoveNextFunc moveNextFunc; private long targetCount; private int itemIndex; + [AllowNull] + private T current; internal Enumerator(T item) { - this.Current = item; + this.current = item; this.circularBuffer = null; this.items = null; this.targetCount = -1; @@ -169,7 +174,7 @@ internal Enumerator(T item) internal Enumerator(CircularBuffer circularBuffer, long targetCount) { - this.Current = null; + this.current = null; this.items = null; this.circularBuffer = circularBuffer; this.targetCount = targetCount; @@ -179,7 +184,7 @@ internal Enumerator(CircularBuffer circularBuffer, long targetCount) internal Enumerator(T[] items, long targetCount) { - this.Current = null; + this.current = null; this.circularBuffer = null; this.items = items; this.targetCount = targetCount; @@ -188,10 +193,10 @@ internal Enumerator(T[] items, long targetCount) } /// - public T Current { get; private set; } + public readonly T Current => this.current; /// - object IEnumerator.Current => this.Current; + readonly object? IEnumerator.Current => this.current; /// public void Dispose() @@ -205,7 +210,7 @@ public bool MoveNext() } /// - public void Reset() + public readonly void Reset() => throw new NotSupportedException(); } } diff --git a/src/OpenTelemetry/BatchExportProcessor.cs b/src/OpenTelemetry/BatchExportProcessor.cs index 943acf10a9b..d42c9464325 100644 --- a/src/OpenTelemetry/BatchExportProcessor.cs +++ b/src/OpenTelemetry/BatchExportProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Diagnostics; using System.Threading; diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 9e5ed04df1c..05ee2bcfda2 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -11,6 +11,20 @@ null-valued tag. ([#3325](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3325)) +* `CompositeProcessor` will now ensure `ParentProvider` is set on its children + ([#3368](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3368)) + +* Added `ForceFlush` and helper ctors on `OpenTelemetryLoggerProvider` + ([#3364](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3364)) + +* `Timestamp`, `TraceId`, `SpanId`, `TraceFlags`, `TraceState`, `CategoryName`, + `LogLevel`, `EventId`, & `Exception` properties on `LogRecord` now expose + `set` methods + ([#3378](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3378)) + +* Handle possible exception when initializing the default service name. + ([#3405](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3405)) + ## 1.3.0 Released 2022-Jun-03 @@ -22,8 +36,12 @@ Released 2022-June-1 * Fix null reference exception when a metric view does not match an instrument. ([#3285](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3285)) * Swallow `ObjectDisposedException` in `BatchExportProcessor` and -* `PeriodicExportingMetricReader`. + `PeriodicExportingMetricReader`. ([#3291](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3291)) +* Add `ConfigureResource` which can replace SetResourceBuilder more succinctly + in most cases and has greater flexibility (applies to + TracerProvicerBuilder, MeterProviderBuilder, OpenTelemetryLoggingOptions). + ([#3307](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3307)) ## 1.3.0-beta.2 diff --git a/src/OpenTelemetry/CompositeProcessor.cs b/src/OpenTelemetry/CompositeProcessor.cs index 49c2258bd49..a9546ab179a 100644 --- a/src/OpenTelemetry/CompositeProcessor.cs +++ b/src/OpenTelemetry/CompositeProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -79,6 +81,16 @@ public override void OnStart(T data) } } + internal override void SetParentProvider(BaseProvider parentProvider) + { + base.SetParentProvider(parentProvider); + + for (var cur = this.head; cur != null; cur = cur.Next) + { + cur.Value.SetParentProvider(parentProvider); + } + } + /// protected override bool OnForceFlush(int timeoutMilliseconds) { @@ -166,9 +178,9 @@ public DoublyLinkedListNode(BaseProcessor value) this.Value = value; } - public DoublyLinkedListNode Previous { get; set; } + public DoublyLinkedListNode? Previous { get; set; } - public DoublyLinkedListNode Next { get; set; } + public DoublyLinkedListNode? Next { get; set; } } } } diff --git a/src/OpenTelemetry/Internal/CircularBuffer.cs b/src/OpenTelemetry/Internal/CircularBuffer.cs index 16614d00213..069ff70cfa4 100644 --- a/src/OpenTelemetry/Internal/CircularBuffer.cs +++ b/src/OpenTelemetry/Internal/CircularBuffer.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System.Runtime.CompilerServices; using System.Threading; @@ -23,10 +25,10 @@ namespace OpenTelemetry.Internal /// Lock-free implementation of single-reader multi-writer circular buffer. /// /// The type of the underlying value. - internal class CircularBuffer + internal sealed class CircularBuffer where T : class { - private readonly T[] trait; + private readonly T?[] trait; private long head; private long tail; @@ -54,20 +56,20 @@ public int Count { get { - var tailSnapshot = this.tail; - return (int)(this.head - tailSnapshot); + var tailSnapshot = Volatile.Read(ref this.tail); + return (int)(Volatile.Read(ref this.head) - tailSnapshot); } } /// /// Gets the number of items added to the . /// - public long AddedCount => this.head; + public long AddedCount => Volatile.Read(ref this.head); /// /// Gets the number of items removed from the . /// - public long RemovedCount => this.tail; + public long RemovedCount => Volatile.Read(ref this.tail); /// /// Adds the specified item to the buffer. @@ -83,22 +85,21 @@ public bool Add(T value) while (true) { - var tailSnapshot = this.tail; - var headSnapshot = this.head; + var tailSnapshot = Volatile.Read(ref this.tail); + var headSnapshot = Volatile.Read(ref this.head); if (headSnapshot - tailSnapshot >= this.Capacity) { return false; // buffer is full } - var head = Interlocked.CompareExchange(ref this.head, headSnapshot + 1, headSnapshot); - if (head != headSnapshot) + if (Interlocked.CompareExchange(ref this.head, headSnapshot + 1, headSnapshot) != headSnapshot) { continue; } - var index = (int)(head % this.Capacity); - this.trait[index] = value; + Volatile.Write(ref this.trait[headSnapshot % this.Capacity], value); + return true; } } @@ -125,16 +126,15 @@ public bool TryAdd(T value, int maxSpinCount) while (true) { - var tailSnapshot = this.tail; - var headSnapshot = this.head; + var tailSnapshot = Volatile.Read(ref this.tail); + var headSnapshot = Volatile.Read(ref this.head); if (headSnapshot - tailSnapshot >= this.Capacity) { return false; // buffer is full } - var head = Interlocked.CompareExchange(ref this.head, headSnapshot + 1, headSnapshot); - if (head != headSnapshot) + if (Interlocked.CompareExchange(ref this.head, headSnapshot + 1, headSnapshot) != headSnapshot) { if (spinCountDown-- == 0) { @@ -144,8 +144,8 @@ public bool TryAdd(T value, int maxSpinCount) continue; } - var index = (int)(head % this.Capacity); - this.trait[index] = value; + Volatile.Write(ref this.trait[headSnapshot % this.Capacity], value); + return true; } } @@ -161,19 +161,19 @@ public bool TryAdd(T value, int maxSpinCount) [MethodImpl(MethodImplOptions.AggressiveInlining)] public T Read() { - var index = (int)(this.tail % this.Capacity); + var tail = Volatile.Read(ref this.tail); + var index = (int)(tail % this.Capacity); while (true) { - var value = this.trait[index]; - if (value == null) + var previous = Interlocked.Exchange(ref this.trait[index], null); + if (previous == null) { // If we got here it means a writer isn't done. continue; } - this.trait[index] = null; - this.tail++; - return value; + Volatile.Write(ref this.tail, tail + 1); + return previous; } } } diff --git a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs index 0db72d4cba7..1dcd65fd94b 100644 --- a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs +++ b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs @@ -390,6 +390,12 @@ public void UnsupportedAttributeType(string type, string key) this.WriteEvent(42, type.ToString(), key); } + [Event(43, Message = "ForceFlush invoked for processor type '{0}' returned result '{1}'.", Level = EventLevel.Verbose)] + public void ProcessorForceFlushInvoked(string processorType, bool result) + { + this.WriteEvent(43, processorType, result); + } + #if DEBUG public class OpenTelemetryEventListener : EventListener { diff --git a/examples/AspNet/Models/WeatherForecast.cs b/src/OpenTelemetry/Internal/Shims/IsExternalInit.cs similarity index 63% rename from examples/AspNet/Models/WeatherForecast.cs rename to src/OpenTelemetry/Internal/Shims/IsExternalInit.cs index 71e8983c6dd..de19a976dd5 100644 --- a/examples/AspNet/Models/WeatherForecast.cs +++ b/src/OpenTelemetry/Internal/Shims/IsExternalInit.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,18 +14,12 @@ // limitations under the License. // -using System; - -namespace Examples.AspNet.Models +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER +namespace System.Runtime.CompilerServices { - public class WeatherForecast + // This enabled "init" keyword in net462 + netstandard2.0 targets. + internal sealed class IsExternalInit { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); - - public string Summary { get; set; } } } +#endif diff --git a/src/OpenTelemetry/Internal/Shims/NullableAttributes.cs b/src/OpenTelemetry/Internal/Shims/NullableAttributes.cs new file mode 100644 index 00000000000..78bcfeab9ae --- /dev/null +++ b/src/OpenTelemetry/Internal/Shims/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 diff --git a/src/OpenTelemetry/Logs/LogRecord.cs b/src/OpenTelemetry/Logs/LogRecord.cs index 94722fd4cad..98c937e7244 100644 --- a/src/OpenTelemetry/Logs/LogRecord.cs +++ b/src/OpenTelemetry/Logs/LogRecord.cs @@ -29,6 +29,8 @@ namespace OpenTelemetry.Logs /// public sealed class LogRecord { + internal LogRecordData Data; + private static readonly Action> AddScopeToBufferedList = (object? scope, List state) => { state.Add(scope); @@ -36,6 +38,7 @@ public sealed class LogRecord private List? bufferedScopes; + // Note: Some users are calling this with reflection. Try not to change the signature to be nice. internal LogRecord( IExternalScopeProvider? scopeProvider, DateTime timestamp, @@ -47,71 +50,107 @@ internal LogRecord( Exception? exception, IReadOnlyList>? stateValues) { - this.ScopeProvider = scopeProvider; - - var activity = Activity.Current; - if (activity != null) + this.Data = new(Activity.Current) { - this.TraceId = activity.TraceId; - this.SpanId = activity.SpanId; - this.TraceState = activity.TraceStateString; - this.TraceFlags = activity.ActivityTraceFlags; - } + TimestampBacking = timestamp, - this.Timestamp = timestamp; - this.CategoryName = categoryName; - this.LogLevel = logLevel; - this.EventId = eventId; - this.FormattedMessage = formattedMessage; - this.State = state; + CategoryName = categoryName, + LogLevel = logLevel, + EventId = eventId, + Message = formattedMessage, + Exception = exception, + }; + + this.ScopeProvider = scopeProvider; this.StateValues = stateValues; - this.Exception = exception; + this.State = state; } /// - /// Gets the log timestamp. + /// Gets or sets the log timestamp. /// - public DateTime Timestamp { get; } + /// + /// Note: If is set to a value with it will be automatically converted to + /// UTC using . + /// + public DateTime Timestamp + { + get => this.Data.Timestamp; + set => this.Data.Timestamp = value; + } /// - /// Gets the log . + /// Gets or sets the log . /// - public ActivityTraceId TraceId { get; } + public ActivityTraceId TraceId + { + get => this.Data.TraceId; + set => this.Data.TraceId = value; + } /// - /// Gets the log . + /// Gets or sets the log . /// - public ActivitySpanId SpanId { get; } + public ActivitySpanId SpanId + { + get => this.Data.SpanId; + set => this.Data.SpanId = value; + } /// - /// Gets the log . + /// Gets or sets the log . /// - public ActivityTraceFlags TraceFlags { get; } + public ActivityTraceFlags TraceFlags + { + get => this.Data.TraceFlags; + set => this.Data.TraceFlags = value; + } /// - /// Gets the log trace state. + /// Gets or sets the log trace state. /// - public string? TraceState { get; } + public string? TraceState + { + get => this.Data.TraceState; + set => this.Data.TraceState = value; + } /// - /// Gets the log category name. + /// Gets or sets the log category name. /// - public string CategoryName { get; } + public string? CategoryName + { + get => this.Data.CategoryName; + set => this.Data.CategoryName = value; + } /// - /// Gets the log . + /// Gets or sets the log . /// - public LogLevel LogLevel { get; } + public LogLevel LogLevel + { + get => this.Data.LogLevel; + set => this.Data.LogLevel = value; + } /// - /// Gets the log . + /// Gets or sets the log . /// - public EventId EventId { get; } + public EventId EventId + { + get => this.Data.EventId; + set => this.Data.EventId = value; + } /// /// Gets or sets the log formatted message. /// - public string? FormattedMessage { get; set; } + public string? FormattedMessage + { + get => this.Data.Message; + set => this.Data.Message = value; + } /// /// Gets or sets the raw state attached to the log. Set to >? StateValues { get; set; } /// - /// Gets the log . + /// Gets or sets the log . /// - public Exception? Exception { get; } + public Exception? Exception + { + get => this.Data.Exception; + set => this.Data.Exception = value; + } internal IExternalScopeProvider? ScopeProvider { get; set; } @@ -139,13 +182,6 @@ internal LogRecord( /// of creation. All callbacks are guaranteed to be called inline from /// this method. /// - /// - /// Note: Scopes are only available during the lifecycle of the log - /// message being written. If you need to capture scopes to be used - /// later (for example in batching scenarios), call to safely capture the values (incurs - /// allocation). - /// /// State. /// The callback to be executed for every scope object. /// The state object to be passed into the callback. @@ -168,6 +204,15 @@ public void ForEachScope(Action callback, TState } } + /// + /// Gets a reference to the for the log message. + /// + /// . + internal ref LogRecordData GetDataRef() + { + return ref this.Data; + } + /// /// Buffers the scopes attached to the log into a list so that they can /// be safely processed after the log message lifecycle has ended. diff --git a/src/OpenTelemetry/Logs/LogRecordData.cs b/src/OpenTelemetry/Logs/LogRecordData.cs new file mode 100644 index 00000000000..c2411c74d52 --- /dev/null +++ b/src/OpenTelemetry/Logs/LogRecordData.cs @@ -0,0 +1,135 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace OpenTelemetry.Logs +{ + /// + /// Stores details about a log message. + /// + internal struct LogRecordData + { + internal DateTime TimestampBacking = DateTime.UtcNow; + + /// + /// Initializes a new instance of the struct. + /// + /// + /// Note: The property is initialized to automatically. + /// + /// Optional used to populate context fields. + public LogRecordData(Activity? activity = null) + { + if (activity != null) + { + this.TraceId = activity.TraceId; + this.SpanId = activity.SpanId; + this.TraceState = activity.TraceStateString; + this.TraceFlags = activity.ActivityTraceFlags; + } + else + { + this.TraceId = default; + this.SpanId = default; + this.TraceState = null; + this.TraceFlags = ActivityTraceFlags.None; + } + } + + /// + /// Gets or sets the log timestamp. + /// + /// + /// Note: If is set to a value with it will be automatically converted to + /// UTC using . + /// + public DateTime Timestamp + { + readonly get => this.TimestampBacking; + set { this.TimestampBacking = value.Kind == DateTimeKind.Local ? value.ToUniversalTime() : value; } + } + + /// + /// Gets or sets the log . + /// + public ActivityTraceId TraceId { get; set; } + + /// + /// Gets or sets the log . + /// + public ActivitySpanId SpanId { get; set; } + + /// + /// Gets or sets the log . + /// + public ActivityTraceFlags TraceFlags { get; set; } + + /// + /// Gets or sets the log trace state. + /// + public string? TraceState { get; set; } + + /// + /// Gets or sets the log category name. + /// + public string? CategoryName { get; set; } = null; + + /// + /// Gets or sets the log . + /// + public LogLevel LogLevel { get; set; } = LogLevel.Trace; + + /// + /// Gets or sets the log . + /// + public EventId EventId { get; set; } = default; + + /// + /// Gets or sets the log message. + /// + public string? Message { get; set; } = null; + + /// + /// Gets or sets the log . + /// + public Exception? Exception { get; set; } = null; + + internal static void SetActivityContext(ref LogRecordData data, Activity? activity = null) + { + if (activity != null) + { + data.TraceId = activity.TraceId; + data.SpanId = activity.SpanId; + data.TraceState = activity.TraceStateString; + data.TraceFlags = activity.ActivityTraceFlags; + } + else + { + data.TraceId = default; + data.SpanId = default; + data.TraceState = null; + data.TraceFlags = ActivityTraceFlags.None; + } + } + } +} diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 1a779ac63ef..d20fcce2b47 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -16,6 +16,7 @@ #nullable enable +using System; using System.Collections.Generic; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -73,6 +74,8 @@ public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processo /// /// Sets the from which the Resource associated with /// this provider is built from. Overwrites currently set ResourceBuilder. + /// You should usually use instead + /// (call if desired). /// /// from which Resource will be built. /// Returns for chaining. @@ -83,5 +86,18 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui this.ResourceBuilder = resourceBuilder; return this; } + + /// + /// Modify the from which the Resource associated with + /// this provider is built from in-place. + /// + /// An action which modifies the provided in-place. + /// Returns for chaining. + public OpenTelemetryLoggerOptions ConfigureResource(Action configure) + { + Guard.ThrowIfNull(configure, nameof(configure)); + configure(this.ResourceBuilder); + return this; + } } } diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index 0c33a7268a3..c057445c84b 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -16,7 +16,9 @@ #nullable enable +using System; using System.Collections; +using System.Threading; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; @@ -54,6 +56,23 @@ public OpenTelemetryLoggerProvider(IOptionsMonitor o { } + /// + /// Initializes a new instance of the class. + /// + /// configuration callback. + public OpenTelemetryLoggerProvider(Action configure) + : this(BuildOptions(configure ?? throw new ArgumentNullException(nameof(configure)))) + { + } + + /// + /// Initializes a new instance of the class. + /// + public OpenTelemetryLoggerProvider() + : this(BuildOptions(configure: null)) + { + } + internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options) { Guard.ThrowIfNull(options); @@ -112,6 +131,29 @@ public ILogger CreateLogger(string categoryName) return logger; } + /// + /// Flushes all the processors registered under , blocks the current thread + /// until flush completed, shutdown signaled or timed out. + /// + /// + /// The number (non-negative) of milliseconds to wait, or + /// Timeout.Infinite to wait indefinitely. + /// + /// + /// Returns true when force flush succeeded; otherwise, false. + /// + /// + /// Thrown when the timeoutMilliseconds is smaller than -1. + /// + /// + /// This function guarantees thread-safety. + /// + public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite) + { + return this.Processor?.ForceFlush(timeoutMilliseconds) ?? true; + } + internal OpenTelemetryLoggerProvider AddProcessor(BaseProcessor processor) { Guard.ThrowIfNull(processor); @@ -128,11 +170,13 @@ internal OpenTelemetryLoggerProvider AddProcessor(BaseProcessor proce } else { - this.Processor = new CompositeProcessor(new[] + var newCompositeProcessor = new CompositeProcessor(new[] { this.Processor, - processor, }); + newCompositeProcessor.SetParentProvider(this); + newCompositeProcessor.AddProcessor(processor); + this.Processor = newCompositeProcessor; } return this; @@ -156,5 +200,12 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + + private static OpenTelemetryLoggerOptions BuildOptions(Action? configure) + { + OpenTelemetryLoggerOptions options = new(); + configure?.Invoke(options); + return options; + } } } diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs index e3614abb495..aa5a5ace8e5 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs @@ -45,6 +45,16 @@ protected MeterProviderBuilderBase() internal List MetricReaders { get; } = new List(); + internal ResourceBuilder ResourceBuilder + { + get => this.resourceBuilder; + set + { + Debug.Assert(value != null, $"{nameof(this.ResourceBuilder)} must not be set to null"); + this.resourceBuilder = value; + } + } + /// public override MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) { @@ -126,14 +136,6 @@ internal MeterProviderBuilder SetMaxMetricPointsPerMetricStream(int maxMetricPoi return this; } - internal MeterProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) - { - Debug.Assert(resourceBuilder != null, $"{nameof(resourceBuilder)} must not be null"); - - this.resourceBuilder = resourceBuilder; - return this; - } - /// /// Run the configured actions to initialize the . /// diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs index bda417b078d..c9ab4726712 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs @@ -183,6 +183,8 @@ public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterP /// /// Sets the from which the Resource associated with /// this provider is built from. Overwrites currently set ResourceBuilder. + /// You should usually use instead + /// (call if desired). /// /// MeterProviderBuilder instance. /// from which Resource will be built. @@ -191,7 +193,27 @@ public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - meterProviderBuilderBase.SetResourceBuilder(resourceBuilder); + meterProviderBuilderBase.ResourceBuilder = resourceBuilder; + } + + return meterProviderBuilder; + } + + /// + /// Modify the from which the Resource associated with + /// this provider is built from in-place. + /// + /// MeterProviderBuilder instance. + /// An action which modifies the provided in-place. + /// Returns for chaining. + public static MeterProviderBuilder ConfigureResource(this MeterProviderBuilder meterProviderBuilder, Action configure) + { + Guard.ThrowIfNull(meterProviderBuilder, nameof(meterProviderBuilder)); + Guard.ThrowIfNull(configure, nameof(configure)); + + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + configure(meterProviderBuilderBase.ResourceBuilder); } return meterProviderBuilder; diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj index a1f2cf59445..542fcc9e407 100644 --- a/src/OpenTelemetry/OpenTelemetry.csproj +++ b/src/OpenTelemetry/OpenTelemetry.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net462 + net6.0;netstandard2.1;netstandard2.0;net462 OpenTelemetry .NET SDK + + false + + - - + diff --git a/src/OpenTelemetry/README.md b/src/OpenTelemetry/README.md index 0646d685207..e51346cd85e 100644 --- a/src/OpenTelemetry/README.md +++ b/src/OpenTelemetry/README.md @@ -79,7 +79,7 @@ Once built, changes to its configuration is not allowed, with the exception of adding more processors. In most cases, a single `TracerProvider` is created at the application startup, and is disposed when application shuts down. -// TODO: Add Asp.Net Core, Asp.Net notes showing where this code should go. +// TODO: Add Asp.Net Core notes showing where this code should go. The snippet below shows how to build a basic `TracerProvider`. This will create a provider with default configuration, and is not particularly useful. The @@ -238,15 +238,14 @@ is the immutable representation of the entity producing the telemetry. If no `Resource` is explicitly configured, the default is to use a resource indicating this [Telemetry SDK](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#telemetry-sdk). -`SetResourceBuilder` method on `TracerProviderBuilder` can be used to set a -`ResourceBuilder` on the provider. When the provider is built, it automatically +The `ConfigureResource` method on `TracerProviderBuilder` can be used to set a +configure the resource on the provider. When the provider is built, it automatically builds the final `Resource` from the configured `ResourceBuilder`. As with -samplers, there can only be a single `Resource` associated with a provider. If -multiple `SetResourceBuilder` is called, the last one wins. Also, it is not -possible to change the resource builder *after* the provider is built, by -calling the `Build()` method on the `TracerProviderBuilder`. `ResourceBuilder` -offers various methods to construct resource comprising of multiple attributes -from various sources. +samplers, there can only be a single `Resource` associated with a provider. +It is not possible to change the resource builder *after* the provider is +built, by calling the `Build()` method on the `TracerProviderBuilder`. +`ResourceBuilder` offers various methods to construct resource comprising +of multiple attributes from various sources. The snippet below shows configuring a custom `ResourceBuilder` to the provider. @@ -256,7 +255,7 @@ using OpenTelemetry.Resources; using OpenTelemetry.Trace; using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName")) + .ConfigureResource(r => r.AddService("MyServiceName")) .Build(); ``` diff --git a/src/OpenTelemetry/Resources/ResourceBuilder.cs b/src/OpenTelemetry/Resources/ResourceBuilder.cs index c4c8ac15a6e..3abb89ea750 100644 --- a/src/OpenTelemetry/Resources/ResourceBuilder.cs +++ b/src/OpenTelemetry/Resources/ResourceBuilder.cs @@ -15,6 +15,7 @@ // using System.Collections.Generic; +using System.Diagnostics; using OpenTelemetry.Internal; namespace OpenTelemetry.Resources @@ -26,17 +27,34 @@ public class ResourceBuilder { private readonly List resources = new(); - private ResourceBuilder() + static ResourceBuilder() { + var defaultServiceName = "unknown_service"; + + try + { + var processName = Process.GetCurrentProcess().ProcessName; + if (!string.IsNullOrWhiteSpace(processName)) + { + defaultServiceName = $"{defaultServiceName}:{processName}"; + } + } + catch + { + // GetCurrentProcess can throw PlatformNotSupportedException + } + + DefaultResource = new Resource(new Dictionary + { + [ResourceSemanticConventions.AttributeServiceName] = defaultServiceName, + }); } - private static Resource DefaultResource { get; } = new Resource(new Dictionary + private ResourceBuilder() { - [ResourceSemanticConventions.AttributeServiceName] = "unknown_service" - + (string.IsNullOrWhiteSpace(System.Diagnostics.Process.GetCurrentProcess().ProcessName) - ? string.Empty : - ":" + System.Diagnostics.Process.GetCurrentProcess().ProcessName), - }); + } + + private static Resource DefaultResource { get; } /// /// Creates a instance with Default diff --git a/src/OpenTelemetry/SimpleExportProcessor.cs b/src/OpenTelemetry/SimpleExportProcessor.cs index e3c129fa0a5..b7ada68a779 100644 --- a/src/OpenTelemetry/SimpleExportProcessor.cs +++ b/src/OpenTelemetry/SimpleExportProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs index 7ab0f53a70f..708c7bc45b1 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs @@ -38,6 +38,20 @@ protected TracerProviderBuilderBase() { } + /// + /// Gets or sets the from which the Resource associated with + /// this provider is built from. Setting this overwrites currently set ResourceBuilder. + /// + internal ResourceBuilder ResourceBuilder + { + get => this.resourceBuilder; + set + { + Guard.ThrowIfNull(value); + this.resourceBuilder = value; + } + } + /// public override TracerProviderBuilder AddInstrumentation( Func instrumentationFactory) @@ -135,20 +149,6 @@ internal TracerProviderBuilder SetSampler(Sampler sampler) return this; } - /// - /// Sets the from which the Resource associated with - /// this provider is built from. Overwrites currently set ResourceBuilder. - /// - /// from which Resource will be built. - /// Returns for chaining. - internal TracerProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) - { - Guard.ThrowIfNull(resourceBuilder); - - this.resourceBuilder = resourceBuilder; - return this; - } - /// /// Adds processor to the provider. /// diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs index 2c1bef0ef5e..24f26e98e01 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs @@ -16,6 +16,7 @@ using System; using System.Diagnostics; +using OpenTelemetry.Internal; using OpenTelemetry.Resources; namespace OpenTelemetry.Trace @@ -61,6 +62,8 @@ public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tracer /// /// Sets the from which the Resource associated with /// this provider is built from. Overwrites currently set ResourceBuilder. + /// You should usually use instead + /// (call if desired). /// /// TracerProviderBuilder instance. /// from which Resource will be built. @@ -69,7 +72,27 @@ public static TracerProviderBuilder SetResourceBuilder(this TracerProviderBuilde { if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderBase.SetResourceBuilder(resourceBuilder); + tracerProviderBuilderBase.ResourceBuilder = resourceBuilder; + } + + return tracerProviderBuilder; + } + + /// + /// Modify the from which the Resource associated with + /// this provider is built from in-place. + /// + /// TracerProviderBuilder instance. + /// An action which modifies the provided in-place. + /// Returns for chaining. + public static TracerProviderBuilder ConfigureResource(this TracerProviderBuilder tracerProviderBuilder, Action configure) + { + Guard.ThrowIfNull(tracerProviderBuilder, nameof(tracerProviderBuilder)); + Guard.ThrowIfNull(configure, nameof(configure)); + + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) + { + configure(tracerProviderBuilderBase.ResourceBuilder); } return tracerProviderBuilder; diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index cd760e29548..88f4e15e2b9 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -277,11 +277,13 @@ internal TracerProviderSdk AddProcessor(BaseProcessor processor) } else { - this.processor = new CompositeProcessor(new[] + var newCompositeProcessor = new CompositeProcessor(new[] { this.processor, - processor, }); + newCompositeProcessor.SetParentProvider(this); + newCompositeProcessor.AddProcessor(processor); + this.processor = newCompositeProcessor; } return this; diff --git a/test/Benchmarks/Benchmarks.csproj b/test/Benchmarks/Benchmarks.csproj index f488c7c293d..dd12abe97eb 100644 --- a/test/Benchmarks/Benchmarks.csproj +++ b/test/Benchmarks/Benchmarks.csproj @@ -4,7 +4,6 @@ Exe net6.0;net462 - false diff --git a/test/Benchmarks/Instrumentation/InstrumentedHttpClientBenchmark.cs b/test/Benchmarks/Instrumentation/InstrumentedHttpClientBenchmark.cs index 7f719db01ab..ff2555eaeb3 100644 --- a/test/Benchmarks/Instrumentation/InstrumentedHttpClientBenchmark.cs +++ b/test/Benchmarks/Instrumentation/InstrumentedHttpClientBenchmark.cs @@ -52,7 +52,7 @@ public void GlobalSetup() this.tracerProvider = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(ServiceName)) + .ConfigureResource(r => r.AddService(ServiceName)) .AddSource(SourceName) .Build(); diff --git a/test/OpenTelemetry.Exporter.Jaeger.Tests/OpenTelemetry.Exporter.Jaeger.Tests.csproj b/test/OpenTelemetry.Exporter.Jaeger.Tests/OpenTelemetry.Exporter.Jaeger.Tests.csproj index 32705554ecf..5531e9421a6 100644 --- a/test/OpenTelemetry.Exporter.Jaeger.Tests/OpenTelemetry.Exporter.Jaeger.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Jaeger.Tests/OpenTelemetry.Exporter.Jaeger.Tests.csproj @@ -4,8 +4,6 @@ net6.0 $(TargetFrameworks);net462 - - false diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj index 95b2de799bf..74af7200119 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj @@ -5,7 +5,6 @@ net6.0 $(TargetFrameworks);net462 $(TARGET_FRAMEWORK) - false diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 202b1212d55..3dd760c4190 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -140,15 +140,15 @@ public void ToOtlpResourceSpansTest(bool includeServiceNameInResource) resourceBuilder.AddService("service-name", "ns1"); } + var exportedItems = new List(); var builder = Sdk.CreateTracerProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddSource(sources[0].Name) - .AddSource(sources[1].Name); + .AddSource(sources[1].Name) + .AddProcessor(new SimpleActivityExportProcessor(new InMemoryExporter(exportedItems))); using var openTelemetrySdk = builder.Build(); - var exportedItems = new List(); - var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); const int numOfSpans = 10; bool isEven; for (var i = 0; i < numOfSpans; i++) @@ -161,8 +161,7 @@ public void ToOtlpResourceSpansTest(bool includeServiceNameInResource) using Activity activity = source.StartActivity($"span-{i}", activityKind, parentContext: default, activityTags); } - processor.Shutdown(); - + Assert.Equal(10, exportedItems.Count); var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); RunTest(batch); @@ -184,7 +183,9 @@ void RunTest(Batch batch) Assert.Contains(otlpResource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceName && kvp.Value.ToString().Contains("unknown_service:")); } - foreach (var scope in request.ResourceSpans.First().ScopeSpans) + var scopeSpans = request.ResourceSpans.First().ScopeSpans; + Assert.Equal(2, scopeSpans.Count); + foreach (var scope in scopeSpans) { Assert.Equal(numOfSpans / 2, scope.Spans.Count); Assert.NotNull(scope.Scope); diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj index 9d8b6e138c4..f1d422947fc 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj @@ -4,8 +4,6 @@ net6.0 $(TargetFrameworks);net462 - - false diff --git a/test/OpenTelemetry.Exporter.ZPages.Tests/OpenTelemetry.Exporter.ZPages.Tests.csproj b/test/OpenTelemetry.Exporter.ZPages.Tests/OpenTelemetry.Exporter.ZPages.Tests.csproj index 6fad2133834..dca1ff0d21e 100644 --- a/test/OpenTelemetry.Exporter.ZPages.Tests/OpenTelemetry.Exporter.ZPages.Tests.csproj +++ b/test/OpenTelemetry.Exporter.ZPages.Tests/OpenTelemetry.Exporter.ZPages.Tests.csproj @@ -4,7 +4,6 @@ net6.0 $(TargetFrameworks);net462 - false diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj index 84e82aec248..7649dc09d3c 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj @@ -4,7 +4,6 @@ net6.0 $(TargetFrameworks);net462 - false diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/InMemoryExporterMetricsExtensionsTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/InMemoryExporterMetricsExtensionsTests.cs new file mode 100644 index 00000000000..eb39eef62ec --- /dev/null +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/InMemoryExporterMetricsExtensionsTests.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. +// + +#if NETCOREAPP3_1_OR_GREATER + +using System; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using System.Net; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; + +using Xunit; + +namespace OpenTelemetry.Extensions.Hosting.Tests +{ + /// + /// These tests verify that works with . + /// + public class InMemoryExporterMetricsExtensionsTests + { + [Fact] + public async Task DeferredMeterProviderBuilder_WithMetric() + { + var meterName = Utils.GetCurrentMethodName(); + var exportedItems = new List(); + + await RunMetricsTest( + configure: builder => builder + .AddMeter(meterName) + .AddInMemoryExporter(exportedItems), + testAction: () => + { + using var meter = new Meter(meterName); + var counter = meter.CreateCounter("meter"); + counter.Add(10); + }); + + Assert.Single(exportedItems); + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + Assert.True(metricPointsEnumerator.MoveNext()); + Assert.Equal(10, metricPointsEnumerator.Current.GetSumLong()); + } + + [Fact] + public async Task DeferredMeterProviderBuilder_WithMetricSnapshot() + { + var meterName = Utils.GetCurrentMethodName(); + var exportedItems = new List(); + + await RunMetricsTest( + configure: builder => builder + .AddMeter(meterName) + .AddInMemoryExporter(exportedItems), + testAction: () => + { + using var meter = new Meter(meterName); + var counter = meter.CreateCounter("meter"); + counter.Add(10); + }); + + Assert.Single(exportedItems); + Assert.Equal(10, exportedItems[0].MetricPoints[0].GetSumLong()); + } + + private static async Task RunMetricsTest(Action configure, Action testAction) + { + using var host = await new HostBuilder() + .ConfigureWebHost(webBuilder => webBuilder + .UseTestServer() + .ConfigureServices(services => services.AddOpenTelemetryMetrics(configure)) + .Configure(app => app.Run(httpContext => + { + testAction.Invoke(); + + var meterProvider = app.ApplicationServices.GetRequiredService(); + meterProvider.ForceFlush(); + + return Task.CompletedTask; + }))) + .StartAsync(); + + using var response = await host.GetTestClient().GetAsync($"/{nameof(RunMetricsTest)}").ConfigureAwait(false); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + await host.StopAsync().ConfigureAwait(false); + } + } +} +#endif diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj index a17774b6bbf..c56dfc18e8f 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj @@ -8,8 +8,11 @@ - - + + + + + @@ -23,4 +26,12 @@ + + + + + + + + diff --git a/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs b/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs new file mode 100644 index 00000000000..05f174561b1 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs @@ -0,0 +1,235 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR 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 OpenTelemetry.Context.Propagation; +using Xunit; + +namespace OpenTelemetry.Extensions.Propagators.Tests +{ + public class JaegerPropagatorTest + { + private const string JaegerHeader = "uber-trace-id"; + private const string JaegerDelimiter = ":"; + private const string JaegerDelimiterEncoded = "%3A"; + + private const string TraceId = "0007651916cd43dd8448eb211c803177"; + private const string TraceIdShort = "7651916cd43dd8448eb211c803177"; + private const string SpanId = "0007c989f9791877"; + private const string SpanIdShort = "7c989f9791877"; + private const string ParentSpanId = "0"; + private const string FlagSampled = "1"; + private const string FlagNotSampled = "0"; + + private static readonly Func, string, IEnumerable> Getter = (headers, name) => + { + if (headers.TryGetValue(name, out var value)) + { + return value; + } + + return Array.Empty(); + }; + + private static readonly Action, string, string> Setter = (carrier, name, value) => + { + carrier[name] = value; + }; + + [Fact] + public void ExtractReturnsOriginalContextIfContextIsAlreadyValid() + { + // arrange + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var spanId = ActivitySpanId.CreateFromString(SpanId.AsSpan()); + var propagationContext = new PropagationContext( + new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, isRemote: true), + default); + + var headers = new Dictionary(); + + // act + var result = new JaegerPropagator().Extract(propagationContext, headers, Getter); + + // assert + Assert.Equal(propagationContext, result); + } + + [Fact] + public void ExtractReturnsOriginalContextIfCarrierIsNull() + { + // arrange + var propagationContext = default(PropagationContext); + + // act + var result = new JaegerPropagator().Extract(propagationContext, null, Getter!); + + // assert + Assert.Equal(propagationContext, result); + } + + [Fact] + public void ExtractReturnsOriginalContextIfGetterIsNull() + { + // arrange + var propagationContext = default(PropagationContext); + + var headers = new Dictionary(); + + // act + var result = new JaegerPropagator().Extract(propagationContext, headers, null); + + // assert + Assert.Equal(propagationContext, result); + } + + [Theory] + [InlineData("", SpanId, ParentSpanId, FlagSampled, JaegerDelimiter)] + [InlineData(TraceId, "", ParentSpanId, FlagSampled, JaegerDelimiter)] + [InlineData(TraceId, SpanId, "", FlagSampled, JaegerDelimiter)] + [InlineData(TraceId, SpanId, ParentSpanId, "", JaegerDelimiter)] + [InlineData(TraceId, SpanId, ParentSpanId, FlagSampled, "")] + [InlineData("invalid trace id", SpanId, ParentSpanId, FlagSampled, JaegerDelimiter)] + [InlineData(TraceId, "invalid span id", ParentSpanId, FlagSampled, JaegerDelimiter)] + [InlineData(TraceId, SpanId, $"too many {JaegerDelimiter} records", FlagSampled, JaegerDelimiter)] + public void ExtractReturnsOriginalContextIfHeaderIsNotValid(string traceId, string spanId, string parentSpanId, string flags, string delimiter) + { + // arrange + var propagationContext = default(PropagationContext); + + var formattedHeader = string.Join( + delimiter, + traceId, + spanId, + parentSpanId, + flags); + + var headers = new Dictionary { { JaegerHeader, new[] { formattedHeader } } }; + + // act + var result = new JaegerPropagator().Extract(propagationContext, headers, Getter); + + // assert + Assert.Equal(propagationContext, result); + } + + [Theory] + [InlineData(TraceId, SpanId, ParentSpanId, FlagSampled, JaegerDelimiter)] + [InlineData(TraceIdShort, SpanIdShort, ParentSpanId, FlagNotSampled, JaegerDelimiterEncoded)] + public void ExtractReturnsNewContextIfHeaderIsValid(string traceId, string spanId, string parentSpanId, string flags, string delimiter) + { + // arrange + var propagationContext = default(PropagationContext); + + var formattedHeader = string.Join( + delimiter, + traceId, + spanId, + parentSpanId, + flags); + + var headers = new Dictionary { { JaegerHeader, new[] { formattedHeader } } }; + + // act + var result = new JaegerPropagator().Extract(propagationContext, headers, Getter); + + // assert + Assert.Equal(traceId.PadLeft(TraceId.Length, '0'), result.ActivityContext.TraceId.ToString()); + Assert.Equal(spanId.PadLeft(SpanId.Length, '0'), result.ActivityContext.SpanId.ToString()); + Assert.Equal(flags == "1" ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None, result.ActivityContext.TraceFlags); + } + + [Fact] + public void InjectDoesNoopIfContextIsInvalid() + { + // arrange + var propagationContext = default(PropagationContext); + + var headers = new Dictionary(); + + // act + new JaegerPropagator().Inject(propagationContext, headers, Setter); + + // assert + Assert.Empty(headers); + } + + [Fact] + public void InjectDoesNoopIfCarrierIsNull() + { + // arrange + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var spanId = ActivitySpanId.CreateFromString(SpanId.AsSpan()); + var propagationContext = new PropagationContext( + new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, isRemote: true), + default); + + // act + new JaegerPropagator().Inject(propagationContext, null, Setter!); + + // assert + } + + [Fact] + public void InjectDoesNoopIfSetterIsNull() + { + // arrange + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var spanId = ActivitySpanId.CreateFromString(SpanId.AsSpan()); + var propagationContext = new PropagationContext( + new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, isRemote: true), + default); + + var headers = new Dictionary(); + + // act + new JaegerPropagator().Inject(propagationContext, headers, null); + + // assert + Assert.Empty(headers); + } + + [Theory] + [InlineData(FlagSampled)] + [InlineData(FlagNotSampled)] + public void InjectWillAddJaegerFormattedTraceToCarrier(string sampledFlag) + { + // arrange + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var spanId = ActivitySpanId.CreateFromString(SpanId.AsSpan()); + var flags = sampledFlag == "1" ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None; + + var propagationContext = new PropagationContext(new ActivityContext(traceId, spanId, flags, isRemote: true), default); + + var expectedValue = string.Join( + JaegerDelimiter, + traceId, + spanId, + ParentSpanId, + sampledFlag); + + var headers = new Dictionary(); + + // act + new JaegerPropagator().Inject(propagationContext, headers, Setter); + + // assert + Assert.Single(headers); + Assert.Equal(expectedValue, headers[JaegerHeader]); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs deleted file mode 100644 index c5fd34408f6..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ /dev/null @@ -1,546 +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.AspNet.Tests -{ - 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; - - 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 deleted file mode 100644 index ebb5ede4f05..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ /dev/null @@ -1,103 +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.AspNet.Tests -{ - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Threading; - using System.Web; - using System.Web.Hosting; - - 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 deleted file mode 100644 index 0a4edd08a1c..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - 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 deleted file mode 100644 index 4a35d43cdf6..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs +++ /dev/null @@ -1,409 +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.AspNet.Tests -{ - using System.IO; - using System.Xml.Linq; - using Microsoft.Web.XmlTransform; - using Xunit; - - 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 deleted file mode 100644 index 8b070653d48..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ /dev/null @@ -1,439 +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.AspNet.Tests -{ - using System.IO; - using System.Xml.Linq; - using Microsoft.Web.XmlTransform; - using Xunit; - - 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; - } - } -} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs deleted file mode 100644 index d3ded5f6327..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.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; -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 deleted file mode 100644 index 521e857bbaf..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs +++ /dev/null @@ -1,31 +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.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 deleted file mode 100644 index bc1588d001e..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ /dev/null @@ -1,370 +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.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 deleted file mode 100644 index b9fbbbeebeb..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ /dev/null @@ -1,112 +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.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 deleted file mode 100644 index 857fb41d11a..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - Unit test project for OpenTelemetry ASP.NET instrumentation - - net462 - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - - - - - - - - - diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/InProcServerTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/InProcServerTests.cs new file mode 100644 index 00000000000..20b3ef3c602 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/InProcServerTests.cs @@ -0,0 +1,88 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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.Collections.Generic; +using System.Diagnostics; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Tests +{ + public sealed class InProcServerTests : IDisposable + { + private TracerProvider tracerProvider; + private WebApplication app; + private HttpClient client; + private List exportedItems; + + public InProcServerTests() + { + this.exportedItems = new List(); + var builder = WebApplication.CreateBuilder(); + var app = builder.Build(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(this.exportedItems).Build(); + app.MapGet("/", () => "Hello World!"); + app.RunAsync(); + + this.app = app; + this.client = new HttpClient(); + } + + [Fact] + public async void ExampleTest() + { + var res = await this.client.GetStringAsync("http://localhost:5000"); + Assert.NotNull(res); + + this.tracerProvider.ForceFlush(); + for (var i = 0; i < 10; i++) + { + if (this.exportedItems.Count > 0) + { + 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)); + } + + var activity = this.exportedItems[0]; + Assert.Equal(ActivityKind.Server, activity.Kind); + Assert.Equal("localhost:5000", activity.GetTagValue(SemanticConventions.AttributeHttpHost)); + Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeHttpMethod)); + Assert.Equal("1.1", activity.GetTagValue(SemanticConventions.AttributeHttpFlavor)); + Assert.Equal(200, activity.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); + } + + public async void Dispose() + { + this.tracerProvider.Dispose(); + this.client.Dispose(); + await this.app.DisposeAsync(); + } + } +} +#endif diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs index fc68255324f..80f09a9a972 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs @@ -115,6 +115,8 @@ public async Task SuccessfulTemplateControllerCallGeneratesASpan( Assert.Equal(ActivityKind.Server, activity.Kind); Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeHttpHost)); Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeHttpMethod)); + Assert.Equal("1.1", activity.GetTagValue(SemanticConventions.AttributeHttpFlavor)); + Assert.Equal("http", activity.GetTagValue(SemanticConventions.AttributeHttpScheme)); Assert.Equal(urlPath, activity.GetTagValue(SemanticConventions.AttributeHttpTarget)); Assert.Equal($"http://localhost{urlPath}{query}", activity.GetTagValue(SemanticConventions.AttributeHttpUrl)); Assert.Equal(statusCode, activity.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 9dfb1f1db50..4d93ba9a7b5 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -120,7 +120,7 @@ public async Task RequestMetricIsCaptured() var method = new KeyValuePair(SemanticConventions.AttributeHttpMethod, "GET"); var scheme = new KeyValuePair(SemanticConventions.AttributeHttpScheme, "http"); var statusCode = new KeyValuePair(SemanticConventions.AttributeHttpStatusCode, "200"); - var flavor = new KeyValuePair(SemanticConventions.AttributeHttpFlavor, "HTTP/1.1"); + var flavor = new KeyValuePair(SemanticConventions.AttributeHttpFlavor, "1.1"); var host = new KeyValuePair(SemanticConventions.AttributeHttpHost, "localhost"); var target = new KeyValuePair(SemanticConventions.AttributeHttpTarget, "api/Values"); Assert.Contains(method, attributes); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.netcore31.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.netcore31.cs index 4cf0ff75a49..a21cedc93a5 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.netcore31.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.netcore31.cs @@ -66,7 +66,6 @@ public async Task HttpOutCallsAreCollectedSuccessfullyAsync(HttpTestData.HttpOut using (Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation((opt) => { - opt.SetHttpFlavor = tc.SetHttpFlavor; opt.Enrich = ActivityEnrichment; opt.RecordException = tc.RecordException ?? false; }) @@ -202,6 +201,7 @@ public async Task DebugIndividualTestAsync() ""http.method"": ""GET"", ""http.host"": ""{host}:{port}"", ""http.status_code"": ""399"", + ""http.flavor"": ""2.0"", ""http.url"": ""http://{host}:{port}/"" } } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs index 803eba5b668..38e1dd83391 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs @@ -74,8 +74,6 @@ public class HttpOutTestCase public bool? SpanStatusHasDescription { get; set; } public Dictionary SpanAttributes { get; set; } - - public bool SetHttpFlavor { get; set; } } } } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs index 14c3347da41..3d3e10a0400 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs @@ -50,7 +50,6 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpTestData.HttpOutTestCase tc .AddProcessor(activityProcessor.Object) .AddHttpClientInstrumentation(options => { - options.SetHttpFlavor = tc.SetHttpFlavor; options.Enrich = ActivityEnrichment; options.RecordException = tc.RecordException.HasValue ? tc.RecordException.Value : false; }) diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json b/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json index eac94c334d9..b938d83305d 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json @@ -1,4 +1,4 @@ -[ +[ { "name": "Successful GET call to localhost", "method": "GET", @@ -9,6 +9,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/" } @@ -23,6 +24,7 @@ "spanAttributes": { "http.method": "POST", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/" } @@ -38,6 +40,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/path/to/resource/" } @@ -53,6 +56,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/path/to/resource#fragment" } @@ -68,6 +72,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/path/to/resource#fragment" } @@ -84,6 +89,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com", + "http.flavor": "2.0", "http.url": "https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/" } }, @@ -99,6 +105,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com", + "http.flavor": "2.0", "http.url": "https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/" } }, @@ -113,6 +120,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/" } @@ -128,6 +136,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": 200, "http.url": "http://{host}:{port}/" } @@ -143,6 +152,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "399", "http.url": "http://{host}:{port}/" } @@ -158,6 +168,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "400", "http.url": "http://{host}:{port}/" } @@ -173,6 +184,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "401", "http.url": "http://{host}:{port}/" } @@ -188,6 +200,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "403", "http.url": "http://{host}:{port}/" } @@ -203,6 +216,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "404", "http.url": "http://{host}:{port}/" } @@ -218,6 +232,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "429", "http.url": "http://{host}:{port}/" } @@ -233,6 +248,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "501", "http.url": "http://{host}:{port}/" } @@ -248,6 +264,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "503", "http.url": "http://{host}:{port}/" } @@ -263,6 +280,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "504", "http.url": "http://{host}:{port}/" } @@ -278,6 +296,7 @@ "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", + "http.flavor": "2.0", "http.status_code": "600", "http.url": "http://{host}:{port}/" } @@ -290,7 +309,6 @@ "spanName": "HTTP GET", "spanStatus": "UNSET", "responseExpected": true, - "setHttpFlavor": true, "spanAttributes": { "http.method": "GET", "http.host": "{host}:{port}", diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/InProcessServer.cs b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/InProcessServer.cs index 9cb29488de2..31010ff2f9c 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/InProcessServer.cs +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/InProcessServer.cs @@ -23,9 +23,6 @@ #if NETCOREAPP3_1 using TestApp.AspNetCore._3._1; #endif -#if NET5_0 -using TestApp.AspNetCore._5._0; -#endif #if NET6_0 using TestApp.AspNetCore._6._0; #endif diff --git a/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj b/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj index 7bfd0cdf3a0..2444f4b2cd3 100644 --- a/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj +++ b/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj @@ -4,7 +4,6 @@ Exe net6.0;net5.0;netcoreapp3.1;net462 - false diff --git a/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj b/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj index 467e98c07fa..d26012a2ae3 100644 --- a/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj +++ b/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj @@ -4,17 +4,13 @@ Exe net6.0;net462 - false + - - - - diff --git a/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj b/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj index 93013144bd4..567a743ba23 100644 --- a/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj +++ b/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj @@ -3,7 +3,6 @@ Exe net6.0;net462 - false diff --git a/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs b/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs index 387a9162623..7a53095574e 100644 --- a/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs +++ b/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs @@ -15,6 +15,9 @@ // using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace OpenTelemetry.Internal.Tests @@ -109,5 +112,66 @@ public void CheckAddedCountAndCount() Assert.Equal(1, circularBuffer.RemovedCount); Assert.Equal(1, circularBuffer.Count); } + + [Fact] + public async Task CpuPressureTest() + { + if (Environment.ProcessorCount < 2) + { + return; + } + + var circularBuffer = new CircularBuffer(2048); + + List tasks = new(); + + int numberOfItemsPerWorker = 100_000; + + for (int i = 0; i < Environment.ProcessorCount; i++) + { + int tid = i; + + tasks.Add(Task.Run(async () => + { + await Task.Delay(2000).ConfigureAwait(false); + + if (tid == 0) + { + for (int i = 0; i < numberOfItemsPerWorker * (Environment.ProcessorCount - 1); i++) + { + SpinWait wait = default; + while (true) + { + if (circularBuffer.Count > 0) + { + circularBuffer.Read(); + break; + } + + wait.SpinOnce(); + } + } + } + else + { + for (int i = 0; i < numberOfItemsPerWorker; i++) + { + SpinWait wait = default; + while (true) + { + if (circularBuffer.Add("item")) + { + break; + } + + wait.SpinOnce(); + } + } + } + })); + } + + await Task.WhenAll(tasks).ConfigureAwait(false); + } } } diff --git a/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs b/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs index 37dd5615106..05305be10ff 100644 --- a/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs +++ b/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs @@ -746,15 +746,14 @@ public void ParseStateValuesUsingCustomTest() private static ILoggerFactory InitializeLoggerFactory(out List exportedItems, Action configure = null) { - exportedItems = new List(); - var exporter = new InMemoryExporter(exportedItems); - var processor = new TestLogRecordProcessor(exporter); + var items = exportedItems = new List(); + return LoggerFactory.Create(builder => { builder.AddOpenTelemetry(options => { configure?.Invoke(options); - options.AddProcessor(processor); + options.AddInMemoryExporter(items); }); builder.AddFilter(typeof(LogRecordTest).FullName, LogLevel.Trace); }); @@ -841,21 +840,6 @@ private class CustomState { public string Property { get; set; } } - - private class TestLogRecordProcessor : SimpleExportProcessor - { - public TestLogRecordProcessor(BaseExporter exporter) - : base(exporter) - { - } - - public override void OnEnd(LogRecord data) - { - data.BufferLogScopes(); - - base.OnEnd(data); - } - } } } #endif diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs new file mode 100644 index 00000000000..330fa4b50e7 --- /dev/null +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs @@ -0,0 +1,89 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR 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 Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Logs.Tests +{ + public sealed class OpenTelemetryLoggerProviderTests + { + [Fact] + public void DefaultCtorTests() + { + OpenTelemetryLoggerOptions defaults = new(); + + using OpenTelemetryLoggerProvider provider = new(); + + Assert.Equal(defaults.IncludeScopes, provider.IncludeScopes); + Assert.Equal(defaults.IncludeFormattedMessage, provider.IncludeFormattedMessage); + Assert.Equal(defaults.ParseStateValues, provider.ParseStateValues); + Assert.Null(provider.Processor); + Assert.NotNull(provider.Resource); + } + + [Fact] + public void ConfigureCtorTests() + { + OpenTelemetryLoggerOptions defaults = new(); + + using OpenTelemetryLoggerProvider provider = new(options => + { + options.IncludeScopes = !defaults.IncludeScopes; + options.IncludeFormattedMessage = !defaults.IncludeFormattedMessage; + options.ParseStateValues = !defaults.ParseStateValues; + + options.SetResourceBuilder(ResourceBuilder + .CreateEmpty() + .AddAttributes(new[] { new KeyValuePair("key1", "value1") })); + + options.AddInMemoryExporter(new List()); + }); + + Assert.Equal(!defaults.IncludeScopes, provider.IncludeScopes); + Assert.Equal(!defaults.IncludeFormattedMessage, provider.IncludeFormattedMessage); + Assert.Equal(!defaults.ParseStateValues, provider.ParseStateValues); + Assert.NotNull(provider.Processor); + Assert.NotNull(provider.Resource); + Assert.Contains(provider.Resource.Attributes, value => value.Key == "key1" && (string)value.Value == "value1"); + } + + [Fact] + public void ForceFlushTest() + { + using OpenTelemetryLoggerProvider provider = new(); + + Assert.True(provider.ForceFlush()); + + List exportedItems = new(); + + provider.AddProcessor(new BatchLogRecordExportProcessor(new InMemoryExporter(exportedItems))); + + var logger = provider.CreateLogger("TestLogger"); + + logger.LogInformation("hello world"); + + Assert.Empty(exportedItems); + + Assert.True(provider.ForceFlush()); + + Assert.Single(exportedItems); + } + } +} diff --git a/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTests.cs new file mode 100644 index 00000000000..254edf887b2 --- /dev/null +++ b/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTests.cs @@ -0,0 +1,168 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR 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.Metrics; + +using OpenTelemetry.Tests; + +using Xunit; + +namespace OpenTelemetry.Metrics.Tests +{ + public class MetricSnapshotTests + { + [Fact] + public void VerifySnapshot_Counter() + { + var exportedMetrics = new List(); + var exportedSnapshots = new List(); + + using var meter = new Meter(Utils.GetCurrentMethodName()); + var counter = meter.CreateCounter("meter"); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInMemoryExporter(exportedMetrics) + .AddInMemoryExporter(exportedSnapshots) + .Build(); + + // FIRST EXPORT + counter.Add(10); + meterProvider.ForceFlush(); + + // Verify Metric 1 + Assert.Single(exportedMetrics); + var metric1 = exportedMetrics[0]; + var metricPoints1Enumerator = metric1.GetMetricPoints().GetEnumerator(); + Assert.True(metricPoints1Enumerator.MoveNext()); + ref readonly var metricPoint1 = ref metricPoints1Enumerator.Current; + Assert.Equal(10, metricPoint1.GetSumLong()); + + // Verify Snapshot 1 + Assert.Single(exportedSnapshots); + var snapshot1 = exportedSnapshots[0]; + Assert.Single(snapshot1.MetricPoints); + Assert.Equal(10, snapshot1.MetricPoints[0].GetSumLong()); + + // Verify Metric == Snapshot + Assert.Equal(metric1.Name, snapshot1.Name); + Assert.Equal(metric1.Description, snapshot1.Description); + Assert.Equal(metric1.Unit, snapshot1.Unit); + Assert.Equal(metric1.MeterName, snapshot1.MeterName); + Assert.Equal(metric1.MetricType, snapshot1.MetricType); + Assert.Equal(metric1.MeterVersion, snapshot1.MeterVersion); + + // SECOND EXPORT + counter.Add(5); + meterProvider.ForceFlush(); + + // Verify Metric 1, after second export + // This value is expected to be updated. + Assert.Equal(15, metricPoint1.GetSumLong()); + + // Verify Metric 2 + Assert.Equal(2, exportedMetrics.Count); + var metric2 = exportedMetrics[1]; + var metricPoints2Enumerator = metric2.GetMetricPoints().GetEnumerator(); + Assert.True(metricPoints2Enumerator.MoveNext()); + ref readonly var metricPoint2 = ref metricPoints2Enumerator.Current; + Assert.Equal(15, metricPoint2.GetSumLong()); + + // Verify Snapshot 1, after second export + // This value is expected to be unchanged. + Assert.Equal(10, snapshot1.MetricPoints[0].GetSumLong()); + + // Verify Snapshot 2 + Assert.Equal(2, exportedSnapshots.Count); + var snapshot2 = exportedSnapshots[1]; + Assert.Single(snapshot2.MetricPoints); + Assert.Equal(15, snapshot2.MetricPoints[0].GetSumLong()); + } + + [Fact] + public void VerifySnapshot_Histogram() + { + var exportedMetrics = new List(); + var exportedSnapshots = new List(); + + using var meter = new Meter(Utils.GetCurrentMethodName()); + var histogram = meter.CreateHistogram("histogram"); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInMemoryExporter(exportedMetrics) + .AddInMemoryExporter(exportedSnapshots) + .Build(); + + // FIRST EXPORT + histogram.Record(10); + meterProvider.ForceFlush(); + + // Verify Metric 1 + Assert.Single(exportedMetrics); + var metric1 = exportedMetrics[0]; + var metricPoints1Enumerator = metric1.GetMetricPoints().GetEnumerator(); + Assert.True(metricPoints1Enumerator.MoveNext()); + ref readonly var metricPoint1 = ref metricPoints1Enumerator.Current; + Assert.Equal(1, metricPoint1.GetHistogramCount()); + Assert.Equal(10, metricPoint1.GetHistogramSum()); + + // Verify Snapshot 1 + Assert.Single(exportedSnapshots); + var snapshot1 = exportedSnapshots[0]; + Assert.Single(snapshot1.MetricPoints); + Assert.Equal(1, snapshot1.MetricPoints[0].GetHistogramCount()); + Assert.Equal(10, snapshot1.MetricPoints[0].GetHistogramSum()); + + // Verify Metric == Snapshot + Assert.Equal(metric1.Name, snapshot1.Name); + Assert.Equal(metric1.Description, snapshot1.Description); + Assert.Equal(metric1.Unit, snapshot1.Unit); + Assert.Equal(metric1.MeterName, snapshot1.MeterName); + Assert.Equal(metric1.MetricType, snapshot1.MetricType); + Assert.Equal(metric1.MeterVersion, snapshot1.MeterVersion); + + // SECOND EXPORT + histogram.Record(5); + meterProvider.ForceFlush(); + + // Verify Metric 1 after second export + // This value is expected to be updated. + Assert.Equal(2, metricPoint1.GetHistogramCount()); + Assert.Equal(15, metricPoint1.GetHistogramSum()); + + // Verify Metric 2 + Assert.Equal(2, exportedMetrics.Count); + var metric2 = exportedMetrics[1]; + var metricPoints2Enumerator = metric2.GetMetricPoints().GetEnumerator(); + Assert.True(metricPoints2Enumerator.MoveNext()); + ref readonly var metricPoint2 = ref metricPoints2Enumerator.Current; + Assert.Equal(2, metricPoint2.GetHistogramCount()); + Assert.Equal(15, metricPoint2.GetHistogramSum()); + + // Verify Snapshot 1 after second export + // This value is expected to be unchanged. + Assert.Equal(1, snapshot1.MetricPoints[0].GetHistogramCount()); + Assert.Equal(10, snapshot1.MetricPoints[0].GetHistogramSum()); + + // Verify Snapshot 2 + Assert.Equal(2, exportedSnapshots.Count); + var snapshot2 = exportedSnapshots[1]; + Assert.Single(snapshot2.MetricPoints); + Assert.Equal(2, snapshot2.MetricPoints[0].GetHistogramCount()); + Assert.Equal(15, snapshot2.MetricPoints[0].GetHistogramSum()); + } + } +} diff --git a/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs b/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs index c73f212cab7..37522f89aac 100644 --- a/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs +++ b/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs @@ -99,5 +99,30 @@ public void CompositeActivityProcessor_ForceFlush(int timeout) Assert.True(p1.ForceFlushCalled); Assert.True(p2.ForceFlushCalled); } + + [Fact] + public void CompositeActivityProcessor_ForwardsParentProvider() + { + using TracerProvider provider = new TestProvider(); + + using var p1 = new TestActivityProcessor(null, null); + using var p2 = new TestActivityProcessor(null, null); + + using var processor = new CompositeProcessor(new[] { p1, p2 }); + + Assert.Null(processor.ParentProvider); + Assert.Null(p1.ParentProvider); + Assert.Null(p2.ParentProvider); + + processor.SetParentProvider(provider); + + Assert.Equal(provider, processor.ParentProvider); + Assert.Equal(provider, p1.ParentProvider); + Assert.Equal(provider, p2.ParentProvider); + } + + private sealed class TestProvider : TracerProvider + { + } } } diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs index a18a24df015..7463df95843 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs @@ -700,9 +700,11 @@ public void SdkProcessesLegacyActivityEvenAfterAddingNewProcessor() // AddLegacyOperationName chained to TracerProviderBuilder using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(testActivityProcessor) - .AddLegacySource(operationNameForLegacyActivity) - .Build(); + .AddProcessor(testActivityProcessor) + .AddLegacySource(operationNameForLegacyActivity) + .Build(); + + Assert.Equal(tracerProvider, testActivityProcessor.ParentProvider); Activity activity = new Activity(operationNameForLegacyActivity); activity.Start(); @@ -736,6 +738,12 @@ public void SdkProcessesLegacyActivityEvenAfterAddingNewProcessor() tracerProvider.AddProcessor(testActivityProcessorNew); + var sdkProvider = (TracerProviderSdk)tracerProvider; + + Assert.True(sdkProvider.Processor is CompositeProcessor); + Assert.Equal(tracerProvider, sdkProvider.Processor.ParentProvider); + Assert.Equal(tracerProvider, testActivityProcessorNew.ParentProvider); + Activity activityNew = new Activity(operationNameForLegacyActivity); // Create a new Activity with the same operation name activityNew.Start(); activityNew.Stop(); @@ -1060,11 +1068,15 @@ public void AddLegacyOperationNameAddsActivityListenerForEmptyActivitySource() Assert.True(emptyActivitySource.HasListeners()); } - [Fact] - public void TracerProviderSdkBuildsWithSDKResource() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void TracerProviderSdkBuildsWithSDKResource(bool useConfigure) { - var tracerProvider = Sdk.CreateTracerProviderBuilder().SetResourceBuilder( - ResourceBuilder.CreateDefault().AddTelemetrySdk()).Build(); + var tracerProvider = useConfigure ? + Sdk.CreateTracerProviderBuilder().SetResourceBuilder( + ResourceBuilder.CreateDefault().AddTelemetrySdk()).Build() : + Sdk.CreateTracerProviderBuilder().ConfigureResource(r => r.AddTelemetrySdk()).Build(); var resource = tracerProvider.GetResource(); var attributes = resource.Attributes;