Skip to content

Commit 600b385

Browse files
authored
[CI Visibility] - BenchmarkDotNet framework support (DataDog#3774)
* Initial commit * . * Changes and fixes. * Changes * remove unused attribute * Changes and fixes * Add BenchmarkDotNet project to UpdateVersion util. * Update and fix version * Fixes * Api changes. * Fixes * Include Datadog.Trace.BenchmarkDotNet project to nuget pack. * Add nuget configuration. * Fix * Add sourcelink * Remove comment * Changes from review * Add Datadog.Trace.BenchmarkDotNet.Tests * Fixes * Fix missing item. * Changes from review * Removing incompatible target frameworks. * Fix * fixes * Reduce allocations and improve performance. (tested with microbenchmark) * Add README.md file * change
1 parent d7b8938 commit 600b385

31 files changed

+1195
-193
lines changed

Diff for: Datadog.Trace.sln

+7
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.NetActivitySdk", "t
508508
EndProject
509509
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Owin.Iis.WebApi2", "tracer\test\test-applications\aspnet\Samples.Owin.Iis.WebApi2\Samples.Owin.Iis.WebApi2.csproj", "{B417E258-A21F-4546-B78F-8A7A4879472A}"
510510
EndProject
511+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Datadog.Trace.BenchmarkDotNet.Tests", "tracer\test\Datadog.Trace.BenchmarkDotNet.Tests\Datadog.Trace.BenchmarkDotNet.Tests.csproj", "{CC549AFF-0EC0-4AD4-93E3-F05C8A74F4D9}"
512+
EndProject
511513
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.InstrumentedTests", "tracer\test\test-applications\integrations\Samples.InstrumentedTests\Samples.InstrumentedTests.csproj", "{64E32F7A-8989-480E-AFE7-3BD343424F6A}"
512514
EndProject
513515
Global
@@ -1190,6 +1192,10 @@ Global
11901192
{0D546118-B70A-44D0-B675-39EDB99FCEEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
11911193
{0D546118-B70A-44D0-B675-39EDB99FCEEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
11921194
{0D546118-B70A-44D0-B675-39EDB99FCEEE}.Release|Any CPU.Build.0 = Release|Any CPU
1195+
{CC549AFF-0EC0-4AD4-93E3-F05C8A74F4D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1196+
{CC549AFF-0EC0-4AD4-93E3-F05C8A74F4D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
1197+
{CC549AFF-0EC0-4AD4-93E3-F05C8A74F4D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
1198+
{CC549AFF-0EC0-4AD4-93E3-F05C8A74F4D9}.Release|Any CPU.Build.0 = Release|Any CPU
11931199
{64E32F7A-8989-480E-AFE7-3BD343424F6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
11941200
{64E32F7A-8989-480E-AFE7-3BD343424F6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
11951201
{64E32F7A-8989-480E-AFE7-3BD343424F6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -1404,6 +1410,7 @@ Global
14041410
{CB56AC5A-D2C1-40DE-99D5-DCF9F44C9482} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
14051411
{560E1104-9A6E-41E7-AB3D-85BA2740A0F7} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
14061412
{B417E258-A21F-4546-B78F-8A7A4879472A} = {AFA0AB23-64F0-4AC1-9050-6CE8FE06F580}
1413+
{CC549AFF-0EC0-4AD4-93E3-F05C8A74F4D9} = {8CEC2042-F11C-49F5-A674-2355793B600A}
14071414
{64E32F7A-8989-480E-AFE7-3BD343424F6A} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
14081415
EndGlobalSection
14091416
GlobalSection(ExtensibilityGlobals) = postSolution

Diff for: docs/Datadog.Trace.BenchmarkDotNet/README.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Datadog.Trace.BenchmarkDotNet NuGet package
2+
3+
This package contains the BenchmarkDotNet exporter and instrumentation for [Datadog CI Visibility](https://docs.datadoghq.com/continuous_integration/).
4+
5+
## Compatibility
6+
7+
- `BenchmarkDotNet 0.13.2` and above
8+
9+
## Getting Started
10+
11+
1. Add the `Datadog.Trace.BenchmarkDotNet` NuGet package to your project, using `dotnet add package Datadog.Trace.BenchmarkDotNet`, for example.
12+
2. Configure your project to use the Datadog.Trace.BenchmarkDotNet exporter, as [described below](#configure-the-project)
13+
3. Configure your CI provider to report via the Datadog Agent or agentless, [as described in the documentation](https://docs.datadoghq.com/continuous_integration/tests/dotnet/?tab=onpremisesciproviderdatadogagent#configuring-reporting-method)
14+
4. Run the benchmark project and check results on [Datadog CI Test Visibility](https://docs.datadoghq.com/continuous_integration/tests/).
15+
16+
### Configure the project
17+
18+
There's two way to configure a benchmark project to use the Datadog's exporter:
19+
20+
#### By Attribute
21+
22+
Add the `DatadogDiagnoser` attribute to the benchmark class.
23+
24+
```csharp
25+
using BenchmarkDotNet.Attributes;
26+
using Datadog.Trace.BenchmarkDotNet;
27+
28+
[DatadogDiagnoser]
29+
[MemoryDiagnoser]
30+
public class OperationBenchmark
31+
{
32+
[Benchmark]
33+
public void Operation()
34+
{
35+
// ...
36+
}
37+
}
38+
```
39+
40+
#### By Configuration
41+
42+
Use the `WithDatadog()` extension method on the current project configuration:
43+
44+
```csharp
45+
using BenchmarkDotNet.Configs;
46+
using BenchmarkDotNet.Running;
47+
using Datadog.Trace.BenchmarkDotNet;
48+
49+
var config = DefaultConfig.Instance
50+
.WithDatadog();
51+
52+
BenchmarkRunner.Run<OperationBenchmark>(config);
53+
```
54+
55+
## Get in touch
56+
57+
If you have questions, feedback, or feature requests, reach our [support](https://docs.datadoghq.com/help).

Diff for: tracer/build/_build/Build.GitHub.cs

+1
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ await client.Issue.Milestone.Update(
438438
"tracer/src/Datadog.Tracer.Native/Resource.rc",
439439
"tracer/src/Datadog.Tracer.Native/version.h",
440440
"tracer/src/Datadog.Trace.MSBuild/Datadog.Trace.MSBuild.csproj",
441+
"tracer/src/Datadog.Trace.BenchmarkDotNet/Datadog.Trace.BenchmarkDotNet.csproj",
441442
"tracer/src/Datadog.Trace.OpenTracing/Datadog.Trace.OpenTracing.csproj",
442443
"tracer/src/Datadog.Trace.Tools.Runner/Datadog.Trace.Tools.Runner.csproj",
443444
"tracer/src/Datadog.Trace/Datadog.Trace.csproj",

Diff for: tracer/build/_build/Build.Steps.cs

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ partial class Build
111111
Solution.GetProject(Projects.DatadogTrace),
112112
Solution.GetProject(Projects.DatadogTraceOpenTracing),
113113
Solution.GetProject(Projects.DatadogTraceAnnotations),
114+
Solution.GetProject(Projects.DatadogTraceBenchmarkDotNet),
114115
};
115116

116117
Project[] ParallelIntegrationTests => new[]

Diff for: tracer/build/_build/PrepareRelease/SetAllVersions.cs

+4
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ public override void Run()
268268
"src/Datadog.Trace.MSBuild/Datadog.Trace.MSBuild.csproj",
269269
NugetVersionReplace);
270270

271+
SynchronizeVersion(
272+
"src/Datadog.Trace.BenchmarkDotNet/Datadog.Trace.BenchmarkDotNet.csproj",
273+
NugetVersionReplace);
274+
271275
SynchronizeVersion(
272276
"src/Datadog.Trace.Tools.Runner/Datadog.Trace.Tools.Runner.csproj",
273277
NugetVersionReplace);

Diff for: tracer/build/_build/Projects.cs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ public static class Projects
55
public const string DatadogTraceAspNet = "Datadog.Trace.AspNet";
66
public const string DatadogTraceBundle = "Datadog.Trace.Bundle";
77
public const string DatadogTraceMsBuild = "Datadog.Trace.MSBuild";
8+
public const string DatadogTraceBenchmarkDotNet = "Datadog.Trace.BenchmarkDotNet";
89
public const string DatadogTraceOpenTracing = "Datadog.Trace.OpenTracing";
910
public const string ClrProfilerNative = "Datadog.Tracer.Native";
1011
public const string NativeLoader = "Datadog.Trace.ClrProfiler.Native";
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<!-- NuGet -->
5-
<Version>1.18.4-prerelease</Version>
6-
<Title>Datadog APM</Title>
7-
<Description>BenchmarkDotNet exporter for Datadog APM</Description>
4+
<Version>2.24.0</Version>
5+
<Title>Datadog CI Visibility - BenchmarkDotNet</Title>
6+
<Description>BenchmarkDotNet exporter for Datadog CI Visibility</Description>
7+
<Nullable>enable</Nullable>
8+
<PackageTags>$(PackageTags);BenchmarkDotNet</PackageTags>
9+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
10+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
11+
<IncludeSymbols>true</IncludeSymbols>
12+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
13+
<PackageReadmeFile>README.md</PackageReadmeFile>
814
</PropertyGroup>
915

1016
<!-- For VS testing purposes only, copy all implementation assemblies to the
@@ -13,10 +19,14 @@
1319
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
1420
</PropertyGroup>
1521
<ItemGroup>
16-
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
22+
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
23+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
1724
</ItemGroup>
1825
<ItemGroup>
1926
<ProjectReference Include="..\Datadog.Trace\Datadog.Trace.csproj" />
2027
</ItemGroup>
2128

29+
<ItemGroup>
30+
<None Include="..\..\..\docs\Datadog.Trace.BenchmarkDotNet\README.md" Pack="true" PackagePath="\" />
31+
</ItemGroup>
2232
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// <copyright file="DatadogColumnHidingRule.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
using BenchmarkDotNet.Columns;
7+
8+
namespace Datadog.Trace.BenchmarkDotNet;
9+
10+
/// <summary>
11+
/// Datadog column hiding rule
12+
/// </summary>
13+
public class DatadogColumnHidingRule : IColumnHidingRule
14+
{
15+
/// <summary>
16+
/// Gets the default instance
17+
/// </summary>
18+
public static IColumnHidingRule Default { get; } = new DatadogColumnHidingRule();
19+
20+
/// <inheritdoc />
21+
public bool NeedToHide(IColumn column)
22+
{
23+
if (column.Id is "StartDate" or "EndDate")
24+
{
25+
return true;
26+
}
27+
28+
return false;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// <copyright file="DatadogDiagnoser.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using BenchmarkDotNet.Analysers;
9+
using BenchmarkDotNet.Columns;
10+
using BenchmarkDotNet.Diagnosers;
11+
using BenchmarkDotNet.Engines;
12+
using BenchmarkDotNet.Exporters;
13+
using BenchmarkDotNet.Loggers;
14+
using BenchmarkDotNet.Reports;
15+
using BenchmarkDotNet.Running;
16+
using BenchmarkDotNet.Validators;
17+
18+
namespace Datadog.Trace.BenchmarkDotNet;
19+
20+
/// <summary>
21+
/// Datadog BenchmarkDotNet Diagnoser
22+
/// </summary>
23+
public class DatadogDiagnoser : IDiagnoser
24+
{
25+
/// <summary>
26+
/// Default DatadogDiagnoser instance
27+
/// </summary>
28+
public static readonly IDiagnoser Default = new DatadogDiagnoser();
29+
30+
private long? _startDateTimeOffset;
31+
private long? _endDateTimeOffset;
32+
33+
/// <inheritdoc />
34+
public IEnumerable<string> Ids { get; } = new[] { "Datadog" };
35+
36+
/// <inheritdoc />
37+
public IEnumerable<IExporter> Exporters { get; } = new[] { DatadogExporter.Default };
38+
39+
/// <inheritdoc />
40+
public IEnumerable<IAnalyser> Analysers { get; } = Array.Empty<IAnalyser>();
41+
42+
/// <inheritdoc />
43+
public RunMode GetRunMode(BenchmarkCase benchmarkCase)
44+
{
45+
return RunMode.NoOverhead;
46+
}
47+
48+
/// <inheritdoc />
49+
public bool RequiresBlockingAcknowledgments(BenchmarkCase benchmarkCase)
50+
{
51+
return false;
52+
}
53+
54+
/// <inheritdoc />
55+
public void Handle(HostSignal signal, DiagnoserActionParameters parameters)
56+
{
57+
if (signal == HostSignal.BeforeProcessStart)
58+
{
59+
_startDateTimeOffset = DateTime.UtcNow.Ticks;
60+
}
61+
else if (signal == HostSignal.AfterProcessExit)
62+
{
63+
_endDateTimeOffset = DateTime.UtcNow.Ticks;
64+
}
65+
}
66+
67+
/// <inheritdoc />
68+
public IEnumerable<Metric> ProcessResults(DiagnoserResults results)
69+
{
70+
yield return new Metric(new DateTimeOffSetMetricDescriptor("StartDate"), _startDateTimeOffset ?? 0d);
71+
yield return new Metric(new DateTimeOffSetMetricDescriptor("EndDate"), _endDateTimeOffset ?? 0d);
72+
}
73+
74+
/// <inheritdoc />
75+
public void DisplayResults(ILogger logger)
76+
{
77+
}
78+
79+
/// <inheritdoc />
80+
public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)
81+
{
82+
yield break;
83+
}
84+
85+
private class DateTimeOffSetMetricDescriptor : IMetricDescriptor
86+
{
87+
public DateTimeOffSetMetricDescriptor(string id) => Id = id;
88+
89+
public string Id { get; }
90+
91+
public string DisplayName => Id;
92+
93+
public string Legend => Id;
94+
95+
public string NumberFormat => "0";
96+
97+
public UnitType UnitType => UnitType.Time;
98+
99+
public string Unit => "ticks";
100+
101+
public bool TheGreaterTheBetter => false;
102+
103+
public int PriorityInCategory => 0;
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// <copyright file="DatadogDiagnoserAttribute.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
using System;
7+
using BenchmarkDotNet.Configs;
8+
9+
namespace Datadog.Trace.BenchmarkDotNet;
10+
11+
/// <summary>
12+
/// Datadog BenchmarkDotNet diagnoser
13+
/// </summary>
14+
public class DatadogDiagnoserAttribute : Attribute, IConfigSource
15+
{
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="DatadogDiagnoserAttribute"/> class.
18+
/// </summary>
19+
public DatadogDiagnoserAttribute()
20+
{
21+
Config = ManualConfig.CreateEmpty()
22+
.WithDatadog();
23+
}
24+
25+
/// <summary>
26+
/// Gets the configuration
27+
/// </summary>
28+
public IConfig Config { get; }
29+
}

0 commit comments

Comments
 (0)