Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.25" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.25" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.25" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.25" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="7.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.25" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.25" />
Expand Down Expand Up @@ -151,11 +152,13 @@
<PackageVersion Update="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="9.0.14" />
<PackageVersion Update="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.14" />
<PackageVersion Update="Microsoft.AspNetCore.SignalR.Client" Version="9.0.14" />
<PackageVersion Update="Microsoft.AspNetCore.TestHost" Version="9.0.14" />
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net10.0'))" Label="Non-production packages, such as for examples and tests, for .NET 10">
<PackageVersion Update="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.5" />
<PackageVersion Update="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.5" />
<PackageVersion Update="Microsoft.AspNetCore.SignalR.Client" Version="10.0.5" />
<PackageVersion Update="Microsoft.AspNetCore.TestHost" Version="10.0.5" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using BenchmarkDotNet.Attributes;
using Greet;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmarks;

[MemoryDiagnoser]
public class AspNetCoreBenchmarks
{
private static readonly Uri BaseAddress = new("/", UriKind.Relative);

private readonly HelloRequest helloRequest = new();
private HttpClient? httpClient;
private Greeter.GreeterClient? grpcClient;
private WebApplication? app;
private TracerProvider? tracerProvider;
private MeterProvider? meterProvider;

[Flags]
public enum EnableInstrumentationOption
{
/// <summary>
/// Instrumentation is not enabled for any signal.
/// </summary>
None = 0,

/// <summary>
/// Instrumentation is enabled only for Traces.
/// </summary>
Traces = 1,

/// <summary>
/// Instrumentation is enabled only for Metrics.
/// </summary>
Metrics = 2,
}

[Params(EnableInstrumentationOption.None, EnableInstrumentationOption.Traces, EnableInstrumentationOption.Metrics, EnableInstrumentationOption.Traces | EnableInstrumentationOption.Metrics)]
public EnableInstrumentationOption EnableInstrumentation { get; set; }

[GlobalSetup]
public async Task StartServer()
{
await this.StartWebApplicationAsync();

KeyValuePair<string, string?>[] config =
[
new("OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION", "true"),
];

IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(config)
.Build();

if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces))
{
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.ConfigureServices((services) => services.AddSingleton(configuration))
.AddAspNetCoreInstrumentation()
.Build();
}

if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics))
{
this.meterProvider = Sdk.CreateMeterProviderBuilder()
.ConfigureServices((services) => services.AddSingleton(configuration))
.AddAspNetCoreInstrumentation()
.Build();
}
}

[GlobalCleanup]
public async Task StopServer()
{
this.httpClient?.Dispose();

if (this.app != null)
{
await this.app.StopAsync();
await this.app.DisposeAsync();
}

this.tracerProvider?.Dispose();
this.meterProvider?.Dispose();
}

[Benchmark]
public async Task HttpGet()
{
using var httpResponse = await this.httpClient!.GetAsync(BaseAddress).ConfigureAwait(false);
httpResponse.EnsureSuccessStatusCode();
}

[Benchmark]
public async Task<HelloReply> GrpcGet() =>
await this.grpcClient!.SayHelloAsync(this.helloRequest);

private async Task StartWebApplicationAsync()
{
var builder = WebApplication.CreateBuilder();

builder.Logging.ClearProviders();
builder.WebHost.UseTestServer();

builder.Services.AddGrpc();

var app = builder.Build();

app.MapGet("/", async context => await context.Response.WriteAsync("Hello World!"));

app.MapGrpcService<GreeterService>();

await app.StartAsync();

this.app = app;
this.httpClient = app.GetTestClient();

var channel = GrpcChannel.ForAddress("http://localhost", new()
{
HttpClient = this.httpClient,
});

this.grpcClient = new Greeter.GreeterClient(channel);
}

private sealed class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) =>
Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
}
}

This file was deleted.

Loading