Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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,146 @@
// 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))
{
var exportedItems = new List<Metric>();

this.meterProvider = Sdk.CreateMeterProviderBuilder()
.ConfigureServices((services) => services.AddSingleton(configuration))
.AddAspNetCoreInstrumentation()
.AddInMemoryExporter(exportedItems)
.Build();
}
Comment thread
martincostello marked this conversation as resolved.
}

[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);
}
Comment thread
martincostello marked this conversation as resolved.

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
Loading