Asp6sample (#2989)
This commit is contained in:
parent
97f21802a3
commit
52258f12e3
|
|
@ -42,7 +42,7 @@
|
|||
<MoqPkgVer>[4.14.5,5.0)</MoqPkgVer>
|
||||
<RabbitMQClientPkgVer>[6.1.0,7.0)</RabbitMQClientPkgVer>
|
||||
<StackExchangeRedisPkgVer>[2.1.58,3.0)</StackExchangeRedisPkgVer>
|
||||
<SwashbuckleAspNetCorePkgVer>[5.0.0]</SwashbuckleAspNetCorePkgVer>
|
||||
<SwashbuckleAspNetCorePkgVer>[6.2.3]</SwashbuckleAspNetCorePkgVer>
|
||||
<XUnitRunnerVisualStudioPkgVer>[2.4.3,3.0)</XUnitRunnerVisualStudioPkgVer>
|
||||
<XUnitPkgVer>[2.4.1,3.0)</XUnitPkgVer>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
a typical ASP.NET Core application, `MeterProvider` lifetime is managed by
|
||||
leveraging the built-in Dependency Injection container as shown
|
||||
[here](../../../examples/AspNetCore/Startup.cs).
|
||||
[here](../../../examples/AspNetCore/Program.cs).
|
||||
|
||||
## MeterProvider configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
a typical ASP.NET Core application, `TracerProvider` lifetime is managed by
|
||||
leveraging the built-in Dependency Injection container as shown
|
||||
[here](../../../examples/AspNetCore/Startup.cs).
|
||||
[here](../../../examples/AspNetCore/Program.cs).
|
||||
|
||||
## TracerProvider configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -14,58 +14,51 @@
|
|||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Examples.AspNetCore.Models;
|
||||
namespace Examples.AspNetCore.Controllers;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Examples.AspNetCore.Controllers
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching",
|
||||
};
|
||||
};
|
||||
|
||||
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]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
using var scope = this.logger.BeginScope("{Id}", Guid.NewGuid().ToString("N"));
|
||||
this.logger.LogInformation(
|
||||
"WeatherForecasts generated {count}: {forecasts}",
|
||||
forecast.Length,
|
||||
forecast);
|
||||
|
||||
// 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
|
||||
{
|
||||
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;
|
||||
}
|
||||
return forecast;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
<IsPackable>false</IsPackable>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.20" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbuckleAspNetCorePkgVer)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<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.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.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.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>
|
||||
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@
|
|||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
|
||||
namespace Examples.AspNetCore.Models
|
||||
namespace Examples.AspNetCore
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
|
|
@ -26,6 +24,6 @@ namespace Examples.AspNetCore.Models
|
|||
|
||||
public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556);
|
||||
|
||||
public string Summary { get; set; }
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,67 +14,163 @@
|
|||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Reflection;
|
||||
using OpenTelemetry.Exporter;
|
||||
using OpenTelemetry.Instrumentation.AspNetCore;
|
||||
using OpenTelemetry.Logs;
|
||||
using OpenTelemetry.Metrics;
|
||||
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)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
case "jaeger":
|
||||
options.AddJaegerExporter();
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
builder.Services.Configure<JaegerExporterOptions>(builder.Configuration.GetSection("Jaeger"));
|
||||
|
||||
// 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>();
|
||||
})
|
||||
.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;
|
||||
});
|
||||
otlpOptions.Endpoint = new Uri(builder.Configuration.GetValue<string>("Otlp:Endpoint"));
|
||||
});
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -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/)
|
||||
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ This exporter allows easy configuration of `ZipkinExporterOptions` from
|
|||
dependency injection container, when used in conjunction with
|
||||
[`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.
|
||||
|
||||
### Configuration using Environment Variables
|
||||
|
|
|
|||
Loading…
Reference in New Issue