Skip to content

Commit 579b06b

Browse files
committed
Added Benchmark.NET Performance Tests
* New project in tests/Serilog.Sinks.MSSqlServer.PerformanceTests * Integrated into release.yml workflow (attach CSV report as file to GitHub release) * Added new perftest.yml workflow without trigger to manually run perf tests * Minor changes in .gitignore, etc.
1 parent 614dbc9 commit 579b06b

10 files changed

+173
-46
lines changed

.github/workflows/perftests.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Performance Tests
2+
3+
on:
4+
# Allows you to run this workflow manually from the Actions tab
5+
workflow_dispatch:
6+
7+
jobs:
8+
build-and-perftest:
9+
runs-on: windows-latest # Build on Windows to ensure .NET Framework targets
10+
steps:
11+
- uses: actions/checkout@v4
12+
13+
- name: Run build
14+
run: ./Build.ps1 -SkipTests
15+
shell: pwsh
16+
17+
- name: Run performance tests
18+
run: ./RunPerfTests.ps1
19+
shell: pwsh

.github/workflows/release.yml

+11-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
workflow_dispatch:
99

1010
jobs:
11-
build-and-release:
11+
build-perftest-and-release:
1212
runs-on: windows-latest # Build on Windows to ensure .NET Framework targets
1313
steps:
1414
- uses: actions/checkout@v4
@@ -35,6 +35,10 @@ jobs:
3535
run: ./Build.ps1 -SkipTests
3636
shell: pwsh
3737

38+
- name: Run performance tests
39+
run: ./RunPerfTests.ps1
40+
shell: pwsh
41+
3842
- name: Get last commit message
3943
id: last_commit
4044
if: success() && github.ref == 'refs/heads/main'
@@ -47,29 +51,27 @@ jobs:
4751
env:
4852
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4953
run: |
50-
# Der Basisname der Dateien basierend auf der Versionsnummer
5154
$baseFileName = "Serilog.Sinks.MSSqlServer.${{ env.VERSION }}"
5255
53-
# Suche die exakten Dateipfade für .nupkg und .snupkg
5456
$nupkgFile = Get-ChildItem -Path "artifacts/$baseFileName*.nupkg" | Select-Object -First 1
5557
$snupkgFile = Get-ChildItem -Path "artifacts/$baseFileName*.snupkg" | Select-Object -First 1
58+
$perfReportSinkFile = Get-ChildItem -Path "artifacts/perftests/Serilog.Sinks.MSSqlServer.PerformanceTests.SinkBenchmarks-report.csv" `
59+
| Select-Object -First 1
5660
57-
# Überprüfe, ob beide Dateien gefunden wurden
5861
if (-not $nupkgFile) { Write-Error "nupkg file not found" ; exit 1 }
5962
if (-not $snupkgFile) { Write-Error "snupkg file not found" ; exit 1 }
63+
if (-not $perfReportSinkFile) { Write-Error "Benchmark report for sink file not found" ; exit 1 }
6064
61-
# Ersetze Backslashes durch Forward Slashes für GitHub CLI-Kompatibilität
6265
$nupkgFilePath = $nupkgFile.FullName -replace '\\', '/'
6366
$snupkgFilePath = $snupkgFile.FullName -replace '\\', '/'
67+
$perfReportSinkFilePath = $perfReportSinkFile.FullName -replace '\\', '/'
6468
65-
# Ausgabe der Dateipfade zu Debugging-Zwecken
66-
Write-Host "Uploading files: $nupkgFilePath, $snupkgFilePath"
69+
Write-Host "Uploading files: $nupkgFilePath, $snupkgFilePath $perfReportPipelineFilePath"
6770
68-
# Erstelle das Release mit den genauen Dateipfaden
6971
gh release create v${{ env.VERSION }} `
7072
--title "v${{ env.VERSION }}" `
7173
--notes "$(Get-Content last_commit_message.txt)" `
72-
$nupkgFilePath $snupkgFilePath
74+
$nupkgFilePath $snupkgFilePath $perfReportSinkFilePath
7375
shell: pwsh
7476

7577
- name: Publish to nuget.org

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ build/
1717
bld/
1818
[Bb]in/
1919
[Oo]bj/
20+
artifacts/
21+
BenchmarkDotNet.Artifacts/
2022

2123
# Roslyn cache directories
2224
*.ide/
@@ -125,7 +127,7 @@ publish/
125127
# Publish Web Output
126128
*.[Pp]ublish.xml
127129
*.azurePubxml
128-
# TODO: Comment the next line if you want to checkin your web deploy settings
130+
# TODO: Comment the next line if you want to checkin your web deploy settings
129131
# but database connection strings (with potential passwords) will be unencrypted
130132
*.pubxml
131133
*.publishproj

Build.ps1

-11
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,6 @@ foreach ($src in Get-ChildItem "$PSScriptRoot/src" -Directory) {
3838
}
3939

4040
if ($SkipTests -eq $false) {
41-
foreach ($test in Get-ChildItem "$PSScriptRoot/test" -Filter "*.PerformanceTests" -Directory) {
42-
Push-Location $test.FullName
43-
44-
echo "build: Building performance test project in $($test.FullName)"
45-
46-
& dotnet build -c Release
47-
if ($LASTEXITCODE -ne 0) { exit 2 }
48-
49-
Pop-Location
50-
}
51-
5241
foreach ($test in Get-ChildItem "$PSScriptRoot/test" -Filter "*.Tests" -Directory) {
5342
Push-Location $test.FullName
5443

Directory.Packages.props

+26-25
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
<Project>
2-
<PropertyGroup>
3-
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4-
</PropertyGroup>
5-
<ItemGroup>
6-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
7-
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
8-
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
9-
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
10-
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.6" />
11-
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
12-
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
13-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
14-
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
15-
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
16-
<PackageVersion Include="coverlet.collector" Version="3.2.0" />
17-
<PackageVersion Include="FluentAssertions" Version="6.7.0" />
18-
<PackageVersion Include="Dapper.StrongName" Version="2.0.123" />
19-
<PackageVersion Include="Moq" Version="4.18.2" />
20-
<PackageVersion Include="xunit" Version="2.9.0" />
21-
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
22-
<PackageVersion Include="Serilog" Version="4.0.0" />
23-
<PackageVersion Include="Serilog.Extensions.Hosting" Version="5.0.1" />
24-
<PackageVersion Include="Serilog.Settings.Configuration" Version="3.4.0" />
25-
</ItemGroup>
26-
</Project>
2+
<PropertyGroup>
3+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
7+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
8+
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
9+
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
10+
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
11+
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.6" />
12+
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
13+
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
14+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
15+
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
16+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
17+
<PackageVersion Include="coverlet.collector" Version="3.2.0" />
18+
<PackageVersion Include="FluentAssertions" Version="6.7.0" />
19+
<PackageVersion Include="Dapper.StrongName" Version="2.0.123" />
20+
<PackageVersion Include="Moq" Version="4.18.2" />
21+
<PackageVersion Include="xunit" Version="2.9.0" />
22+
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
23+
<PackageVersion Include="Serilog" Version="4.0.0" />
24+
<PackageVersion Include="Serilog.Extensions.Hosting" Version="5.0.1" />
25+
<PackageVersion Include="Serilog.Settings.Configuration" Version="3.4.0" />
26+
</ItemGroup>
27+
</Project>

RunPerfTests.ps1

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Push-Location $PSScriptRoot
2+
3+
$artifactsPath = "$PSScriptRoot\artifacts\perftests"
4+
5+
if (Test-Path "$artifactsPath") {
6+
echo "perf: Cleaning $artifactsPath"
7+
Remove-Item "$artifactsPath" -Force -Recurse
8+
}
9+
10+
New-Item -Path "$artifactsPath" -ItemType Directory
11+
12+
$perfTestProjectPath = "$PSScriptRoot/test/Serilog.Sinks.MSSqlServer.PerformanceTests"
13+
Push-Location "$perfTestProjectPath"
14+
15+
echo "perf: Running performance test project in $perfTestProjectPath"
16+
& dotnet run -c Release
17+
18+
cp ".\BenchmarkDotNet.Artifacts\results\*.*" "$artifactsPath\"
19+
Pop-Location
20+
21+
Pop-Location

serilog-sinks-mssqlserver.sln

+9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
3333
.github\workflows\pr-validation.yml = .github\workflows\pr-validation.yml
3434
README.md = README.md
3535
.github\workflows\release.yml = .github\workflows\release.yml
36+
RunPerfTests.ps1 = RunPerfTests.ps1
37+
.github\workflows\perftests.yml = .github\workflows\perftests.yml
3638
EndProjectSection
3739
EndProject
3840
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetStandardDemoLib", "sample\NetStandardDemo\NetStandardDemoLib\NetStandardDemoLib.csproj", "{8E69E31B-61C7-4175-B886-9C2078FCA477}"
@@ -43,6 +45,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetStandardDemo", "NetStand
4345
EndProject
4446
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppConfigDemo", "sample\AppConfigDemo\AppConfigDemo.csproj", "{6BFE1D21-1442-4375-AB69-14160B906A64}"
4547
EndProject
48+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.MSSqlServer.PerformanceTests", "test\Serilog.Sinks.MSSqlServer.PerformanceTests\Serilog.Sinks.MSSqlServer.PerformanceTests.csproj", "{106A6BAF-F8E4-408B-BB09-391330DA87F2}"
49+
EndProject
4650
Global
4751
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4852
Debug|Any CPU = Debug|Any CPU
@@ -81,6 +85,10 @@ Global
8185
{6BFE1D21-1442-4375-AB69-14160B906A64}.Debug|Any CPU.Build.0 = Debug|Any CPU
8286
{6BFE1D21-1442-4375-AB69-14160B906A64}.Release|Any CPU.ActiveCfg = Release|Any CPU
8387
{6BFE1D21-1442-4375-AB69-14160B906A64}.Release|Any CPU.Build.0 = Release|Any CPU
88+
{106A6BAF-F8E4-408B-BB09-391330DA87F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
89+
{106A6BAF-F8E4-408B-BB09-391330DA87F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
90+
{106A6BAF-F8E4-408B-BB09-391330DA87F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
91+
{106A6BAF-F8E4-408B-BB09-391330DA87F2}.Release|Any CPU.Build.0 = Release|Any CPU
8492
EndGlobalSection
8593
GlobalSection(SolutionProperties) = preSolution
8694
HideSolutionNode = FALSE
@@ -95,6 +103,7 @@ Global
95103
{F908C46D-E72E-41E4-975D-73733294F93F} = {7B2B80DE-427A-4FEC-A7CE-7AD81FED73DE}
96104
{7B2B80DE-427A-4FEC-A7CE-7AD81FED73DE} = {AA346332-5BAF-47F1-B8FB-7600ED61265D}
97105
{6BFE1D21-1442-4375-AB69-14160B906A64} = {AA346332-5BAF-47F1-B8FB-7600ED61265D}
106+
{106A6BAF-F8E4-408B-BB09-391330DA87F2} = {F02D6513-6F45-452E-85A0-41A872A2C1F8}
98107
EndGlobalSection
99108
GlobalSection(ExtensibilityGlobals) = postSolution
100109
SolutionGuid = {AAA6BF8D-7B53-4A5F-A79A-D1B306383B45}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using BenchmarkDotNet.Running;
2+
3+
namespace Serilog.Sinks.MSSqlServer.PerformanceTests;
4+
5+
/// <summary>
6+
/// Wrappers that make it easy to run benchmark suites through the <c>dotnet test</c> runner.
7+
/// </summary>
8+
/// <example>
9+
/// <code>dotnet test -c Release --filter "FullyQualifiedName=Serilog.Sinks.MSSqlServer.PerformanceTests.Harness.Pipeline"</code>
10+
/// </example>
11+
public class Program
12+
{
13+
public static void Main()
14+
{
15+
BenchmarkRunner.Run<SinkBenchmarks>();
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
6+
<AssemblyName>Serilog.Sinks.MSSqlServer.PerformanceTests</AssemblyName>
7+
<OutputType>Exe</OutputType>
8+
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
9+
<SignAssembly>true</SignAssembly>
10+
<RuntimeIdentifiers>win</RuntimeIdentifiers>
11+
<PlatformTarget>AnyCPU</PlatformTarget>
12+
<AnalysisLevel>6.0-recommended</AnalysisLevel>
13+
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\..\src\Serilog.Sinks.MSSqlServer\Serilog.Sinks.MSSqlServer.csproj"/>
18+
<PackageReference Include="BenchmarkDotNet" />
19+
</ItemGroup>
20+
21+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using BenchmarkDotNet.Attributes;
2+
3+
namespace Serilog.Sinks.MSSqlServer.PerformanceTests;
4+
5+
[MemoryDiagnoser]
6+
public class SinkBenchmarks
7+
{
8+
private const string _connectionString = @"Data Source=(localdb)\MSSQLLocalDB;Database=LogTest;Integrated Security=SSPI;Encrypt=False;";
9+
private const string _schemaName = "dbo";
10+
private const string _tableName = "LogEvents";
11+
private ILogger _log = null!;
12+
13+
[GlobalSetup]
14+
public void Setup()
15+
{
16+
var options = new ColumnOptions();
17+
options.Store.Add(StandardColumn.LogEvent);
18+
_log = new LoggerConfiguration()
19+
.WriteTo.MSSqlServer(_connectionString,
20+
sinkOptions: new MSSqlServerSinkOptions
21+
{
22+
TableName = _tableName,
23+
SchemaName = _schemaName,
24+
AutoCreateSqlTable = true,
25+
AutoCreateSqlDatabase = true
26+
},
27+
appConfiguration: null,
28+
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Verbose,
29+
formatProvider: null,
30+
columnOptions: options,
31+
columnOptionsSection: null)
32+
.CreateLogger();
33+
}
34+
35+
[Benchmark]
36+
public void EmitLogEvent()
37+
{
38+
_log.Information("Hello, {Name}!", "World");
39+
}
40+
41+
[Benchmark]
42+
public void IntProperties()
43+
{
44+
_log.Information("Hello, {A} {B} {C}!", 1, 2, 3);
45+
}
46+
}

0 commit comments

Comments
 (0)