Skip to content

Commit f1674f6

Browse files
authored
Add benchmarks for single-span diagnostic observer for ASP.NET Core (#7965)
## Summary of changes Adds a micro and macro benchmark for the new observer ## Reason for change Want to verify that it has performance benefits ## Implementation details - Added new scenario for macro - Duplicated existing scenario for micro and run. I would like to have had these as the same methods, but the "global" nature of diagnostic observers makes this difficult I think. ## Test coverage I'll manually trigger a run of the macro ## Other details https://datadoghq.atlassian.net/browse/LANGPLAT-842 Part of a stack - #7962 - #7963 - #7964 - #7966 - #7965 👈
1 parent 4e44d73 commit f1674f6

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

.gitlab/benchmarks/macrobenchmarks.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ calltarget_ngen-x86:
162162
DD_CLR_ENABLE_NGEN: 1
163163
ENDPOINT: "hello"
164164

165+
single_span-x86:
166+
extends: .benchmarks-x86
167+
variables:
168+
NATIVE_PROFILER_PATH: "dd-trace-dotnet/tracer/tracer-home-linux/linux-x64/Datadog.Trace.ClrProfiler.Native.so"
169+
TRACER_HOME_PATH: "dd-trace-dotnet/tracer/tracer-home-linux"
170+
COR_ENABLE_PROFILING: 1
171+
CORECLR_ENABLE_PROFILING: 1
172+
DD_CLR_ENABLE_INLINING: 1
173+
DD_CLR_ENABLE_NGEN: 1
174+
DD_TRACE_SINGLE_SPAN_ASPNETCORE_ENABLED: 1
175+
ENDPOINT: "hello"
176+
165177
trace_stats-x86:
166178
extends: .benchmarks-x86
167179
variables:
@@ -346,6 +358,19 @@ calltarget_ngen-arm64:
346358
DD_CLR_ENABLE_NGEN: 1
347359
ENDPOINT: "hello"
348360

361+
single_span-arm64:
362+
extends: .benchmarks-arm64
363+
tags: ["runner:apm-k8s-arm-metal"]
364+
variables:
365+
NATIVE_PROFILER_PATH: "dd-trace-dotnet/tracer/tracer-home-linux-arm64/linux-arm64/Datadog.Trace.ClrProfiler.Native.so"
366+
TRACER_HOME_PATH: "dd-trace-dotnet/tracer/tracer-home-linux-arm64"
367+
COR_ENABLE_PROFILING: 1
368+
CORECLR_ENABLE_PROFILING: 1
369+
DD_CLR_ENABLE_INLINING: 1
370+
DD_CLR_ENABLE_NGEN: 1
371+
DD_TRACE_SINGLE_SPAN_ASPNETCORE_ENABLED: 1
372+
ENDPOINT: "hello"
373+
349374
trace_stats-arm64:
350375
extends: .benchmarks-arm64
351376
tags: ["runner:apm-k8s-arm-metal"]
@@ -560,6 +585,16 @@ calltarget_ngen-win:
560585
DD_CLR_ENABLE_NGEN: 1
561586
ENDPOINT: "hello"
562587

588+
single_span-win:
589+
extends: .benchmarks-win
590+
variables:
591+
COR_ENABLE_PROFILING: 1
592+
CORECLR_ENABLE_PROFILING: 1
593+
DD_CLR_ENABLE_INLINING: 1
594+
DD_CLR_ENABLE_NGEN: 1
595+
DD_TRACE_SINGLE_SPAN_ASPNETCORE_ENABLED: 1
596+
ENDPOINT: "hello"
597+
563598
trace_stats-win:
564599
extends: .benchmarks-win
565600
variables:

tracer/test/benchmarks/Benchmarks.Trace/AspNetCoreBenchmark.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Collections.Generic;
5+
using System.Diagnostics;
56
using System.Net.Http;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -15,14 +16,18 @@
1516
using Datadog.Trace.Debugger;
1617
using Datadog.Trace.Debugger.SpanCodeOrigin;
1718
using Datadog.Trace.DiagnosticListeners;
19+
using Datadog.Trace.DuckTyping;
1820
using Datadog.Trace.Iast.Settings;
1921
using Datadog.Trace.RemoteConfigurationManagement;
2022
using Datadog.Trace.Security.Unit.Tests.Iast;
23+
using Datadog.Trace.Util;
2124
using Microsoft.AspNetCore.Builder;
2225
using Microsoft.AspNetCore.Hosting;
2326
using Microsoft.AspNetCore.Mvc;
27+
using Microsoft.AspNetCore.Routing;
2428
using Microsoft.AspNetCore.TestHost;
2529
using Microsoft.Extensions.DependencyInjection;
30+
using RoutePattern = Microsoft.AspNetCore.Routing.Patterns.RoutePattern;
2631

2732
namespace Benchmarks.Trace
2833
{
@@ -98,6 +103,80 @@ public void Configure(IApplicationBuilder builder)
98103
}
99104
}
100105
}
106+
#if NET6_0_OR_GREATER
107+
[MemoryDiagnoser]
108+
[BenchmarkCategory(Constants.TracerCategory, Constants.RunOnPrs, Constants.RunOnMaster)]
109+
public class SingleSpanAspNetCoreBenchmark
110+
{
111+
private HttpClient _client;
112+
private Tracer _tracer;
113+
private Security _security;
114+
private Datadog.Trace.Iast.Iast _iast;
115+
private SpanCodeOrigin _spanCodeOrigin;
116+
private DiagnosticManager _diagnosticManager;
117+
private TestServer _testServer;
118+
119+
[GlobalSetup]
120+
public void GlobalSetup()
121+
{
122+
var config = new CustomSettingsForTests(TracerHelper.DefaultConfig);
123+
var settings = new TracerSettings(config, NullConfigurationTelemetry.Instance, new());
124+
125+
_tracer = TracerHelper.CreateTracer(settings);
126+
_security = new Security(new SecuritySettings(config, NullConfigurationTelemetry.Instance), null, new RcmSubscriptionManager());
127+
_iast = new Datadog.Trace.Iast.Iast(new IastSettings(config, NullConfigurationTelemetry.Instance), NullDiscoveryService.Instance);
128+
129+
var builder = new WebHostBuilder()
130+
.UseStartup<Startup>();
131+
132+
_testServer = new TestServer(builder);
133+
_client = _testServer.CreateClient();
134+
135+
var observers = new List<DiagnosticObserver>();
136+
_spanCodeOrigin = new SpanCodeOrigin(new DebuggerSettings(config, NullConfigurationTelemetry.Instance));
137+
observers.Add(new SingleSpanAspNetCoreDiagnosticObserver(_tracer, _security, _iast, _spanCodeOrigin));
138+
_diagnosticManager = new DiagnosticManager(observers);
139+
_diagnosticManager.Start();
140+
141+
// Warmup to initialize middleware pipeline
142+
SingleSpanAspNetCore();
143+
}
144+
145+
[GlobalCleanup]
146+
public void GlobalCleanup()
147+
{
148+
_diagnosticManager.Dispose();
149+
_testServer.Dispose();
150+
_security.Dispose();
151+
_tracer.TracerManager.ShutdownAsync().GetAwaiter().GetResult();
152+
}
153+
154+
[Benchmark]
155+
public string SingleSpanAspNetCore()
156+
{
157+
return _client.GetStringAsync("/Home").GetAwaiter().GetResult();
158+
}
159+
160+
private class Startup
161+
{
162+
public void ConfigureServices(IServiceCollection services)
163+
{
164+
services.AddMvc();
165+
}
166+
167+
public void Configure(IApplicationBuilder builder)
168+
{
169+
builder.UseRouting();
170+
builder.UseEndpoints(endpoints =>
171+
{
172+
endpoints.MapControllerRoute(
173+
name: "default",
174+
pattern: "{controller=Home}/{action=Index}/{id?}");
175+
});
176+
}
177+
}
178+
}
179+
#endif
101180

102181
/// <summary>
103182
/// Simple controller used for the aspnetcore benchmark
@@ -150,6 +229,34 @@ public string CallTargetSendRequest()
150229
return null;
151230
}
152231
}
232+
233+
#if !NET6_0_OR_GREATER
234+
[MemoryDiagnoser]
235+
public class SingleSpanAspNetCoreBenchmark
236+
{
237+
[GlobalSetup]
238+
public void GlobalSetup()
239+
{
240+
}
241+
242+
[GlobalCleanup]
243+
public void GlobalCleanup()
244+
{
245+
}
246+
247+
[Benchmark]
248+
public string SendRequest()
249+
{
250+
return null;
251+
}
252+
253+
[Benchmark]
254+
public string CallTargetSendRequest()
255+
{
256+
return null;
257+
}
258+
}
259+
#endif
153260
}
154261

155262
#endif

0 commit comments

Comments
 (0)