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 b5c5edff456..bad5ff66307 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -75,10 +75,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}" @@ -129,8 +125,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}" @@ -203,10 +197,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}" @@ -311,14 +301,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 @@ -331,10 +313,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 @@ -419,14 +397,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 @@ -497,7 +467,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/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/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 0034b5ce8d7..00000000000 --- a/examples/AspNet/Examples.AspNet.csproj +++ /dev/null @@ -1,156 +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 - - - - - - - - - - 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/Models/WeatherForecast.cs b/examples/AspNet/Models/WeatherForecast.cs deleted file mode 100644 index 71e8983c6dd..00000000000 --- a/examples/AspNet/Models/WeatherForecast.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 System; - -namespace Examples.AspNet.Models -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); - - public string Summary { get; set; } - } -} diff --git a/examples/AspNet/Properties/AssemblyInfo.cs b/examples/AspNet/Properties/AssemblyInfo.cs 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/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.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.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 76b9ffe1cef..2c22ca8c063 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -7,6 +7,10 @@ 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/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index fcca7defd74..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; @@ -194,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/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/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index f8d5e3e3794..05ee2bcfda2 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -22,6 +22,9 @@ `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 diff --git a/src/OpenTelemetry/README.md b/src/OpenTelemetry/README.md index 0f41b3808da..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 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/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 84c20ffb54f..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - Unit test project for ASP.NET HttpModule - - net462 - - - - - - - - - - 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 - - - - - - - - - - - - - - - - - - - -