Asp6sample (#2989)

This commit is contained in:
Xavier 2022-03-10 12:33:12 -08:00 committed by GitHub
parent 97f21802a3
commit 52258f12e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 216 additions and 298 deletions

View File

@ -42,7 +42,7 @@
<MoqPkgVer>[4.14.5,5.0)</MoqPkgVer> <MoqPkgVer>[4.14.5,5.0)</MoqPkgVer>
<RabbitMQClientPkgVer>[6.1.0,7.0)</RabbitMQClientPkgVer> <RabbitMQClientPkgVer>[6.1.0,7.0)</RabbitMQClientPkgVer>
<StackExchangeRedisPkgVer>[2.1.58,3.0)</StackExchangeRedisPkgVer> <StackExchangeRedisPkgVer>[2.1.58,3.0)</StackExchangeRedisPkgVer>
<SwashbuckleAspNetCorePkgVer>[5.0.0]</SwashbuckleAspNetCorePkgVer> <SwashbuckleAspNetCorePkgVer>[6.2.3]</SwashbuckleAspNetCorePkgVer>
<XUnitRunnerVisualStudioPkgVer>[2.4.3,3.0)</XUnitRunnerVisualStudioPkgVer> <XUnitRunnerVisualStudioPkgVer>[2.4.3,3.0)</XUnitRunnerVisualStudioPkgVer>
<XUnitPkgVer>[2.4.1,3.0)</XUnitPkgVer> <XUnitPkgVer>[2.4.1,3.0)</XUnitPkgVer>
</PropertyGroup> </PropertyGroup>

View File

@ -39,7 +39,7 @@ 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 Global.asax.cs file) as shown [here](../../../examples/AspNet/Global.asax.cs). In
a typical ASP.NET Core application, `MeterProvider` lifetime is managed by a typical ASP.NET Core application, `MeterProvider` lifetime is managed by
leveraging the built-in Dependency Injection container as shown leveraging the built-in Dependency Injection container as shown
[here](../../../examples/AspNetCore/Startup.cs). [here](../../../examples/AspNetCore/Program.cs).
## MeterProvider configuration ## MeterProvider configuration

View File

@ -42,7 +42,7 @@ 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 Global.asax.cs file) as shown [here](../../../examples/AspNet/Global.asax.cs). In
a typical ASP.NET Core application, `TracerProvider` lifetime is managed by a typical ASP.NET Core application, `TracerProvider` lifetime is managed by
leveraging the built-in Dependency Injection container as shown leveraging the built-in Dependency Injection container as shown
[here](../../../examples/AspNetCore/Startup.cs). [here](../../../examples/AspNetCore/Program.cs).
## TracerProvider configuration ## TracerProvider configuration

View File

@ -14,58 +14,51 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System; namespace Examples.AspNetCore.Controllers;
using System.Collections.Generic; using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using Examples.AspNetCore.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace Examples.AspNetCore.Controllers [ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{ {
[ApiController] private static readonly string[] Summaries = new[]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{ {
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching",
}; };
private static readonly HttpClient HttpClient = new(); private static readonly HttpClient HttpClient = new HttpClient();
private readonly ILogger<WeatherForecastController> logger; private readonly ILogger<WeatherForecastController> logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger) public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
using var scope = this.logger.BeginScope("{Id}", Guid.NewGuid().ToString("N"));
// Making an http call here to serve as an example of
// how dependency calls will be captured and treated
// automatically as child of incoming request.
var res = HttpClient.GetStringAsync("http://google.com").Result;
var rng = new Random();
var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{ {
this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); Date = DateTime.Now.AddDays(index),
} TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)],
})
.ToArray();
[HttpGet] this.logger.LogInformation(
public IEnumerable<WeatherForecast> Get() "WeatherForecasts generated {count}: {forecasts}",
{ forecast.Length,
using var scope = this.logger.BeginScope("{Id}", Guid.NewGuid().ToString("N")); forecast);
// Making an http call here to serve as an example of return forecast;
// how dependency calls will be captured and treated
// automatically as child of incoming request.
var res = HttpClient.GetStringAsync("http://google.com").Result;
var rng = new Random();
var forecast = 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();
this.logger.LogInformation(
"WeatherForecasts generated {count}: {forecasts}",
forecast.Length,
forecast);
return forecast;
}
} }
} }

View File

@ -1,28 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <Nullable>enable</Nullable>
<NoWarn>$(NoWarn);1591</NoWarn> <ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.20" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbuckleAspNetCorePkgVer)" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbuckleAspNetCorePkgVer)" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Extensions.Hosting\OpenTelemetry.Extensions.Hosting.csproj" /> <ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Extensions.Hosting\OpenTelemetry.Extensions.Hosting.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" /> <ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.OpenTelemetryProtocol\OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj" /> <ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.OpenTelemetryProtocol\OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs.csproj" /> <ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.AspNetCore\OpenTelemetry.Instrumentation.AspNetCore.csproj" /> <ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.AspNetCore\OpenTelemetry.Instrumentation.AspNetCore.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.Http\OpenTelemetry.Instrumentation.Http.csproj" /> <ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.Http\OpenTelemetry.Instrumentation.Http.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -14,9 +14,7 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System; namespace Examples.AspNetCore
namespace Examples.AspNetCore.Models
{ {
public class WeatherForecast public class WeatherForecast
{ {
@ -26,6 +24,6 @@ namespace Examples.AspNetCore.Models
public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556);
public string Summary { get; set; } public string? Summary { get; set; }
} }
} }

View File

@ -14,67 +14,163 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System; using System.Reflection;
using Microsoft.AspNetCore.Hosting; using OpenTelemetry.Exporter;
using Microsoft.Extensions.Configuration; using OpenTelemetry.Instrumentation.AspNetCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs; using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources; using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Examples.AspNetCore var builder = WebApplication.CreateBuilder(args);
var serviceName = "AspNetCoreExampleService";
// OpenTelemetry
var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
// Switch between Zipkin/Jaeger/OTLP by setting UseExporter in appsettings.json.
var tracingExporter = builder.Configuration.GetValue<string>("UseTracingExporter").ToLowerInvariant();
var resourceBuilder = tracingExporter switch
{ {
public class Program "jaeger" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue<string>("Jaeger:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
"zipkin" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue<string>("Zipkin:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
"otlp" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue<string>("Otlp:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
_ => ResourceBuilder.CreateDefault().AddService(serviceName, serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
};
// Traces
builder.Services.AddOpenTelemetryTracing(options =>
{
options
.SetResourceBuilder(resourceBuilder)
.SetSampler(new AlwaysOnSampler())
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation();
switch (tracingExporter)
{ {
public static void Main(string[] args) case "jaeger":
{ options.AddJaegerExporter();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) => builder.Services.Configure<JaegerExporterOptions>(builder.Configuration.GetSection("Jaeger"));
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => // Customize the HttpClient that will be used when JaegerExporter is configured for HTTP transport.
builder.Services.AddHttpClient("JaegerExporter", configureClient: (client) => client.DefaultRequestHeaders.Add("X-MyCustomHeader", "value"));
break;
case "zipkin":
options.AddZipkinExporter();
builder.Services.Configure<ZipkinExporterOptions>(builder.Configuration.GetSection("Zipkin"));
break;
case "otlp":
options.AddOtlpExporter(otlpOptions =>
{ {
webBuilder.UseStartup<Startup>(); otlpOptions.Endpoint = new Uri(builder.Configuration.GetValue<string>("Otlp:Endpoint"));
})
.ConfigureLogging((context, builder) =>
{
builder.ClearProviders();
builder.AddConsole();
var logExporter = context.Configuration.GetValue<string>("UseLogExporter").ToLowerInvariant();
switch (logExporter)
{
case "otlp":
// Adding the OtlpExporter creates a GrpcChannel.
// This switch must be set before creating a GrpcChannel when calling an insecure gRPC service.
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
builder.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(context.Configuration.GetValue<string>("Otlp:ServiceName")));
options.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri(context.Configuration.GetValue<string>("Otlp:Endpoint"));
});
});
break;
default:
builder.AddOpenTelemetry(options =>
{
options.AddConsoleExporter();
});
break;
}
builder.Services.Configure<OpenTelemetryLoggerOptions>(opt =>
{
opt.IncludeScopes = true;
opt.ParseStateValues = true;
opt.IncludeFormattedMessage = true;
});
}); });
break;
default:
options.AddConsoleExporter();
break;
} }
});
// For options which can be bound from IConfiguration.
builder.Services.Configure<AspNetCoreInstrumentationOptions>(builder.Configuration.GetSection("AspNetCoreInstrumentation"));
// Logging
builder.Logging.ClearProviders();
builder.Logging.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(resourceBuilder);
var logExporter = builder.Configuration.GetValue<string>("UseLogExporter").ToLowerInvariant();
switch (logExporter)
{
case "otlp":
options.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri(builder.Configuration.GetValue<string>("Otlp:Endpoint"));
});
break;
default:
options.AddConsoleExporter();
break;
}
});
builder.Services.Configure<OpenTelemetryLoggerOptions>(opt =>
{
opt.IncludeScopes = true;
opt.ParseStateValues = true;
opt.IncludeFormattedMessage = true;
});
// Metrics
builder.Services.AddOpenTelemetryMetrics(options =>
{
options.SetResourceBuilder(resourceBuilder)
.AddHttpClientInstrumentation();
var metricsExporter = builder.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
switch (metricsExporter)
{
case "prometheus":
options.AddPrometheusExporter();
break;
case "otlp":
options.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri(builder.Configuration.GetValue<string>("Otlp:Endpoint"));
});
break;
default:
options.AddConsoleExporter((exporterOptions, metricReaderOptions) =>
{
exporterOptions.Targets = ConsoleExporterOutputTargets.Console;
// The ConsoleMetricExporter defaults to a manual collect cycle.
// This configuration causes metrics to be exported to stdout on a 10s interval.
metricReaderOptions.MetricReaderType = MetricReaderType.Periodic;
metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 10000;
});
break;
}
});
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} }
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
var metricsExporter = builder.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
if (metricsExporter == "prometheus")
{
app.UseOpenTelemetryPrometheusScrapingEndpoint();
}
app.Run();

View File

@ -0,0 +1,19 @@
# OpenTelemetry ASP.Net Core 6 Web API Example
This example uses the new WebApplication host that ships with .Net 6
and shows how to setup
1. OpenTelemetry logging
2. OpenTelemetry metrics
3. OpenTelemetry tracing
`ResourceBuilder` is associated with OpenTelemetry to associate the
service name, version and the machine on which this program is running.
The sample rate is set to emit all the traces using `AlwaysOnSampler`.
You can try out different samplers like `TraceIdRatioBasedSampler`.
## References
* [ASP.NET Core 3.1 Example](https://github.com/open-telemetry/opentelemetry-dotnet/tree/98cb28974af43fc893ab80a8cead6e2d4163e144/examples/AspNetCore)
* [OpenTelemetry Project](https://opentelemetry.io/)

View File

@ -1,184 +0,0 @@
// <copyright file="Startup.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using OpenTelemetry.Exporter;
using OpenTelemetry.Instrumentation.AspNetCore;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Examples.AspNetCore
{
public class Startup
{
public Startup(IConfiguration configuration)
{
this.Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// Enable HttpClientFactory integration for customization of the HttpClient used for export calls.
services.AddHttpClient();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
if (File.Exists(xmlPath))
{
c.IncludeXmlComments(xmlPath);
}
});
// Switch between Zipkin/Jaeger/OTLP by setting UseExporter in appsettings.json.
var tracingExporter = this.Configuration.GetValue<string>("UseTracingExporter").ToLowerInvariant();
switch (tracingExporter)
{
case "jaeger":
services.AddOpenTelemetryTracing((builder) => builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue<string>("Jaeger:ServiceName")))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddJaegerExporter());
services.Configure<JaegerExporterOptions>(this.Configuration.GetSection("Jaeger"));
// Customize the HttpClient that will be used when JaegerExporter is configured for HTTP transport.
services.AddHttpClient("JaegerExporter", configureClient: (client) => client.DefaultRequestHeaders.Add("X-MyCustomHeader", "value"));
break;
case "zipkin":
services.AddOpenTelemetryTracing((builder) => builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue<string>("Zipkin:ServiceName")))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddZipkinExporter());
services.Configure<ZipkinExporterOptions>(this.Configuration.GetSection("Zipkin"));
break;
case "otlp":
// Adding the OtlpExporter creates a GrpcChannel.
// This switch must be set before creating a GrpcChannel when calling an insecure gRPC service.
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
services.AddOpenTelemetryTracing((builder) => builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue<string>("Otlp:ServiceName")))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri(this.Configuration.GetValue<string>("Otlp:Endpoint"));
}));
break;
default:
services.AddOpenTelemetryTracing((builder) => builder
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddConsoleExporter());
// For options which can be bound from IConfiguration.
services.Configure<AspNetCoreInstrumentationOptions>(this.Configuration.GetSection("AspNetCoreInstrumentation"));
// For options which can be configured from code only.
services.Configure<AspNetCoreInstrumentationOptions>(options =>
{
options.Filter = (req) =>
{
return req.Request.Host != null;
};
});
break;
}
var metricsExporter = this.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
services.AddOpenTelemetryMetrics(builder =>
{
builder.AddAspNetCoreInstrumentation();
builder.AddHttpClientInstrumentation();
switch (metricsExporter)
{
case "prometheus":
builder.AddPrometheusExporter();
break;
case "otlp":
builder.AddOtlpExporter();
break;
default:
builder.AddConsoleExporter((exporterOptions, metricReaderOptions) =>
{
exporterOptions.Targets = ConsoleExporterOutputTargets.Console;
// The ConsoleMetricExporter defaults to a manual collect cycle.
// This configuration causes metrics to be exported to stdout on a 10s interval.
metricReaderOptions.MetricReaderType = MetricReaderType.Periodic;
metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 10000;
});
break;
}
});
services.Configure<PrometheusExporterOptions>(this.Configuration.GetSection("Prometheus"));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.UseRouting();
var metricsExporter = this.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
if (metricsExporter == "prometheus")
{
app.UseOpenTelemetryPrometheusScrapingEndpoint();
}
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

View File

@ -60,7 +60,7 @@ This exporter allows easy configuration of `ZipkinExporterOptions` from
dependency injection container, when used in conjunction with dependency injection container, when used in conjunction with
[`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md). [`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md).
See the [Startup](../../examples/AspNetCore/Startup.cs) class of the ASP.NET See the [Startup](../../examples/AspNetCore/Program.cs) class of the ASP.NET
Core application for example use. Core application for example use.
### Configuration using Environment Variables ### Configuration using Environment Variables