Skip to content

Commit 76e30b7

Browse files
committed
update benchmarks and docs
1 parent 13b316f commit 76e30b7

12 files changed

Lines changed: 157 additions & 93 deletions

README.md

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
# Bleess.Extensions.Logging.File
22
High performance rolling file logger for Microsoft.Extensions.Logging with no other 3rd party dependencies. Modeled after the standard console logger.
33

4-
- Rolling files, max file size, max number or files, rolling by time period
4+
- Rolling files, max file size, max number of files, rolling by time period
55
- Text or Json output as well as custom formatters
6-
- Standard idomatic configuration (similar to other MS logging providers) using IConfiguration or configuration callbacks
6+
- Standard idiomatic configuration (similar to other MS logging providers) using IConfiguration or configuration callbacks
77
- Abitity to update settings such as log level, filter rules, or log file path while application is running
88
- Logging scopes and activity tracking support
9-
- High performance using dedicated write thread and
9+
- High performance using dedicated write thread
1010
- Ability to specify multiple log files with independent settings
1111

12-
13-
This project is very similar to nReco/logging with a few additions: multiple files, logging scopes, json output, streamlined configuration, and abiltity to modify settings while running.
14-
1512
## Usage
1613

1714
Add the nuget package Bleess.Extensions.Logging.File
1815

19-
The log provider is configured just like any other Microsoft.Extensions.Logging providers. There are extensions methods on the ILogBuilder to add the provider.
20-
21-
When using Host.CreateDefaultBuilder you only need to call `AddFile()`, and the logger will be configured using configuration providers. There are also other overloads to configure the logger using options callbacks etc.
16+
The log provider is configured just like any other Microsoft.Extensions.Logging providers. There are extensions methods on the ILogBuilder to add the provider.
17+
18+
When using Host.CreateDefaultBuilder you only need to call `AddFile()`, and the logger will be configured using configuration providers. There are also other overloads to configure the logger using options callbacks etc.
2219

2320
```csharp
2421
logBuilder.AddFile();
@@ -139,7 +136,6 @@ Example configuration
139136
},
140137
```
141138

142-
143139
## Rolling Behavior
144140
Log files can have a max file size at which time a new file will be create with a incremented id appended. You may also specify a maximum number of files to retain. Once the maximum number of files has been reached, the oldest will be overwritten.
145141
Using RollInterval setting, you can also specify that a date will be appended to the file name and the files will roll according to the date in 'yyyyMMddHH' format.
@@ -159,16 +155,19 @@ BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3
159155
AMD Ryzen 5 5600H with Radeon Graphics, 1 CPU, 12 logical and 6 physical cores
160156
.NET SDK 8.0.100
161157
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
162-
Job-WGADCC : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
158+
Job-HSNTJM : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
163159

164-
IterationCount=2 LaunchCount=2 WarmupCount=10
160+
IterationCount=10 LaunchCount=2 WarmupCount=10
165161

166162
```
167-
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
168-
|--------------- |-----------:|---------:|----------:|-------:|-------:|----------:|
169-
| BleessWrite | 662.4 ns | 190.9 ns | 29.54 ns | 0.1068 | - | 904 B |
170-
| KaramboloWrite | 1,064.2 ns | 975.5 ns | 150.96 ns | 0.0839 | 0.0381 | 709 B |
171-
| NRecoWrite | 1,585.5 ns | 139.9 ns | 21.65 ns | 0.1621 | 0.0076 | 1371 B |
163+
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
164+
|----------------------- |----------------:|--------------:|--------------:|----------:|---------:|-----------:|
165+
| Bleess_single_write | 659.6 ns | 20.31 ns | 22.57 ns | 0.1068 | 0.0038 | 904 B |
166+
| Karambolo_single_write | 679.7 ns | 82.32 ns | 94.80 ns | 0.0839 | - | 706 B |
167+
| NReco_single_write | 1,547.5 ns | 13.10 ns | 14.56 ns | 0.1640 | 0.0057 | 1373 B |
168+
| Bleess_10000_writes | 6,469,397.9 ns | 163,216.34 ns | 181,414.53 ns | 1078.1250 | - | 9040006 B |
169+
| Karambolo_10000_write | 6,522,278.8 ns | 318,328.54 ns | 366,587.62 ns | 843.7500 | - | 7083785 B |
170+
| NReco_10000_write | 15,962,119.6 ns | 380,106.19 ns | 406,709.37 ns | 1625.0000 | 125.0000 | 13713687 B |
172171

173172

174173
#### Json file
@@ -178,15 +177,17 @@ BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3
178177
AMD Ryzen 5 5600H with Radeon Graphics, 1 CPU, 12 logical and 6 physical cores
179178
.NET SDK 8.0.100
180179
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
181-
Job-WGADCC : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
180+
Job-HSNTJM : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
182181

183-
IterationCount=2 LaunchCount=2 WarmupCount=10
182+
IterationCount=10 LaunchCount=2 WarmupCount=10
184183

185184
```
186-
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
187-
|--------------- |---------:|---------:|----------:|-------:|-------:|----------:|
188-
| BleessWrite | 621.8 ns | 162.6 ns | 25.16 ns | 0.1068 | - | 904 B |
189-
| KaramboloWrite | 985.7 ns | 721.7 ns | 111.68 ns | 0.0839 | 0.0381 | 710 B |
185+
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
186+
|---------------------------- |---------:|----------:|----------:|-------:|-------:|-------:|----------:|
187+
| Bleess_single_write_json | 1.990 μs | 0.0469 μs | 0.0521 μs | 0.9766 | - | - | 7.99 KB |
188+
| Karambolo_single_write_json | 2.118 μs | 0.1781 μs | 0.2051 μs | 0.3204 | 0.0458 | 0.0153 | 2.65 KB |
189+
190+
190191

191192
#### Multi-File
192193
```
@@ -195,19 +196,19 @@ BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3
195196
AMD Ryzen 5 5600H with Radeon Graphics, 1 CPU, 12 logical and 6 physical cores
196197
.NET SDK 8.0.100
197198
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
198-
Job-WGADCC : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
199+
Job-HSNTJM : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
199200

200-
IterationCount=2 LaunchCount=2 WarmupCount=10
201+
IterationCount=10 LaunchCount=2 WarmupCount=10
201202

202203
```
203-
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
204-
|--------------- |---------:|----------:|----------:|-------:|-------:|----------:|
205-
| BleessWrite | 1.441 μs | 0.2313 μs | 0.0358 μs | 0.2213 | - | 1856 B |
206-
| KaramboloWrite | 1.335 μs | 0.2949 μs | 0.0456 μs | 0.0877 | 0.0458 | 734 B |
204+
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
205+
|--------------------------------- |---------:|----------:|----------:|-------:|-------:|----------:|
206+
| Bleess_multifile_single_write | 1.374 μs | 0.0396 μs | 0.0441 μs | 0.1984 | - | 1.67 KB |
207+
| Karambolo_multifile_single_write | 1.554 μs | 0.1430 μs | 0.1647 μs | 0.1602 | 0.0229 | 1.33 KB |
207208

208209

209210
## Credits
210-
- Most of the code was a adapted from dotnet source code (specifically Microsoft.Extensions.Logging.Console) https://github.com/dotnet/runtime/tree/master/src/libraries/Microsoft.Extensions.Logging.Console
211-
- The FileWriter was adapted from https://github.com/nreco/logging
211+
- Some of the code was a adapted from dotnet source code (specifically Microsoft.Extensions.Logging.Console) https://github.com/dotnet/runtime/tree/master/src/libraries/Microsoft.Extensions.Logging.Console
212+
- The FileWriter was originally adapted from https://github.com/nreco/logging, but has since been significantly modified.
212213

213214

benchmark/Benchmarks/Benchmarks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<ItemGroup>
1111
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
1212
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.5.0" Aliases="Karambolo" />
13-
<PackageReference Include="Karambolo.Extensions.Logging.File.Json" Version="3.5.0" />
13+
<PackageReference Include="Karambolo.Extensions.Logging.File.Json" Version="3.5.0" Aliases="Karambolo" />
1414
<PackageReference Include="NReco.Logging.File" Version="1.2.0" Aliases="NReco" />
1515
</ItemGroup>
1616

benchmark/Benchmarks/JsonFileBenchmarks.Karambolo.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ public void SetupKaramboloLogging()
2424
ServiceCollection sc = new ServiceCollection();
2525
sc.AddLogging(logBuilder =>
2626
{
27-
logBuilder.AddFile(o =>
27+
logBuilder.AddJsonFile(o =>
2828
{
29-
o.MaxFileSize = 1024 * 1024 * 1024; // 1 MB
29+
o.MaxFileSize = 1024 * 1024 * 1024; // 1 GB
3030
o.IncludeScopes = false;
31+
o.MaxQueueSize = 1024;
3132

3233
o.Files = new LogFileOptions[]
3334
{
34-
new LogFileOptions{ Path = "logs/karambolo.txt" }
35+
new LogFileOptions{ Path = "logs/karambolo.json" }
3536
};
3637
});
3738
});
@@ -43,7 +44,8 @@ public void SetupKaramboloLogging()
4344

4445

4546
[Benchmark]
46-
public void KaramboloWrite()
47+
[BenchmarkCategory("json")]
48+
public void Karambolo_single_write_json()
4749
{
4850
_karamboloLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
4951
}

benchmark/Benchmarks/JsonFileBenchmarks.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace Benchmarks
1818
{
1919
[MemoryDiagnoser()]
20-
[SimpleJob(launchCount: 2, warmupCount: 10, iterationCount: 2)]
20+
[SimpleJob(2, 10, 10)]
2121
public partial class JsonFileBenchmarks
2222
{
2323

@@ -36,15 +36,14 @@ public void SetupBleessLogging()
3636
ServiceCollection sc = new ServiceCollection();
3737
sc.AddLogging(lobBuilder =>
3838
{
39-
lobBuilder.AddSimpleFile(o =>
39+
lobBuilder.AddJsonFile(o =>
4040
{
4141
o.Path = "logs/Bleess.txt";
42-
o.MaxFileSizeInMB = 1024 * 1024; // 1 GB
42+
o.MaxFileSizeInMB = 1024; // 1 GB
4343
o.MaxNumberFiles = 31;
4444
},
4545
o =>
4646
{
47-
o.SingleLine = true;
4847
o.EmptyLineBetweenMessages = true;
4948
o.IncludeScopes = false;
5049
o.UseUtcTimestamp = true;
@@ -55,14 +54,12 @@ public void SetupBleessLogging()
5554

5655
_bleessLogger = sp.GetRequiredService<Microsoft.Extensions.Logging.ILoggerFactory>().CreateLogger("default");
5756

58-
59-
60-
6157
}
6258

6359

6460
[Benchmark]
65-
public void BleessWrite()
61+
[BenchmarkCategory("json")]
62+
public void Bleess_single_write_json()
6663
{
6764
_bleessLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
6865
}

benchmark/Benchmarks/MultiFileBenchmarks.Karambolo.cs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// alias ns
1414
using Karambolo::Microsoft.Extensions.Logging;
1515
using Karambolo::Karambolo.Extensions.Logging.File;
16+
using Microsoft.Extensions.Options;
1617

1718
namespace Benchmarks
1819
{
@@ -26,13 +27,25 @@ public void SetupKaramboloLogging()
2627
{
2728
logBuilder.AddFile(o =>
2829
{
29-
o.MaxFileSize = 1024 * 1024 * 1024; // 1 MB
30+
o.MaxFileSize = 1024 * 1024 * 1024; // 1 GB
3031
o.IncludeScopes = false;
32+
o.MaxQueueSize = 1024;
3133

32-
o.Files = new LogFileOptions[]
34+
o.Files = new LogFileOptions[]
3335
{
34-
new LogFileOptions{ Path = "logs/karambolo1.txt" },
35-
new LogFileOptions{ Path = "logs/karambolo2.txt" },
36+
new LogFileOptions{ Path = "logs/karambolo1.txt" }
37+
};
38+
});
39+
40+
logBuilder.AddFile<AltFileLoggerProvider>(configure: o =>
41+
{
42+
o.MaxFileSize = 1024 * 1024 * 1024; // 1 GB
43+
o.IncludeScopes = false;
44+
o.MaxQueueSize = 1024;
45+
46+
o.Files = new LogFileOptions[]
47+
{
48+
new LogFileOptions{ Path = "logs/karambolo2.txt" }
3649
};
3750
});
3851
});
@@ -44,9 +57,16 @@ public void SetupKaramboloLogging()
4457

4558

4659
[Benchmark]
47-
public void KaramboloWrite()
60+
[BenchmarkCategory("multifile")]
61+
public void Karambolo_multifile_single_write()
4862
{
4963
_karamboloLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
5064
}
5165
}
66+
67+
[ProviderAlias("File2")]
68+
class AltFileLoggerProvider : FileLoggerProvider
69+
{
70+
public AltFileLoggerProvider(FileLoggerContext context, IOptionsMonitor<FileLoggerOptions> options, string optionsName) : base(context, options, optionsName) { }
71+
}
5272
}

benchmark/Benchmarks/MultiFileBenchmarks.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace Benchmarks
1818
{
1919
[MemoryDiagnoser()]
20-
[SimpleJob(launchCount: 2, warmupCount: 10, iterationCount: 2)]
20+
[SimpleJob(2, 10, 10)]
2121
public partial class MultiFileBenchmarks
2222
{
2323

@@ -71,15 +71,12 @@ public void SetupBleessLogging()
7171
var sp = sc.BuildServiceProvider();
7272

7373
_bleessLogger = sp.GetRequiredService<Microsoft.Extensions.Logging.ILoggerFactory>().CreateLogger("default");
74-
75-
76-
77-
7874
}
7975

8076

8177
[Benchmark]
82-
public void BleessWrite()
78+
[BenchmarkCategory("multifile")]
79+
public void Bleess_multifile_single_write()
8380
{
8481
_bleessLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
8582
}

benchmark/Benchmarks/Program.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ internal class Program
66
{
77
static void Main(string[] args)
88
{
9-
// simple
10-
BenchmarkRunner.Run<SimpleFileBenchmarks>();
11-
12-
// json
13-
BenchmarkRunner.Run<JsonFileBenchmarks>();
14-
15-
// composite
16-
BenchmarkRunner.Run<MultiFileBenchmarks>();
9+
BenchmarkRunner.Run(
10+
[
11+
BenchmarkConverter.TypeToBenchmarks(typeof(SimpleFileBenchmarks)),
12+
BenchmarkConverter.TypeToBenchmarks(typeof(JsonFileBenchmarks)),
13+
BenchmarkConverter.TypeToBenchmarks(typeof(MultiFileBenchmarks))
14+
]);
1715
}
1816
}
1917
}

benchmark/Benchmarks/SimpleFileBenchmarks.Karambolo.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public void SetupKaramboloLogging()
2727
logBuilder.AddFile(o =>
2828
{
2929
o.MaxFileSize = 1024 * 1024 * 1024; // 1 MB
30+
31+
o.MaxQueueSize = 1024;
32+
3033
o.IncludeScopes = false;
3134

3235
o.Files = new LogFileOptions[]
@@ -43,9 +46,20 @@ public void SetupKaramboloLogging()
4346

4447

4548
[Benchmark]
46-
public void KaramboloWrite()
49+
[BenchmarkCategory("text")]
50+
public void Karambolo_single_write()
4751
{
4852
_karamboloLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
4953
}
54+
55+
[Benchmark]
56+
[BenchmarkCategory("text", "10000")]
57+
public void Karambolo_10000_write()
58+
{
59+
for (int i = 0; i < 10000; i++)
60+
{
61+
_karamboloLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
62+
}
63+
}
5064
}
5165
}

benchmark/Benchmarks/SimpleFileBenchmarks.NReco.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void SetupNRecoLogging()
2626
logBuilder.AddFile("logs/NReco.txt", o =>
2727
{
2828

29-
o.FileSizeLimitBytes = 1024 * 1024 * 1024; // 1 MB
29+
o.FileSizeLimitBytes = 1024 * 1024 * 1024; // 1 GB
3030
o.MaxRollingFiles = 31;
3131
o.UseUtcTimestamp = true;
3232
});
@@ -39,9 +39,20 @@ public void SetupNRecoLogging()
3939

4040

4141
[Benchmark]
42-
public void NRecoWrite()
42+
[BenchmarkCategory("text")]
43+
public void NReco_single_write()
4344
{
4445
_nRecoLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
4546
}
47+
48+
[Benchmark]
49+
[BenchmarkCategory("text", "10000")]
50+
public void NReco_10000_write()
51+
{
52+
for (int i = 0; i < 10000; i++)
53+
{
54+
_nRecoLogger!.LogError("This is a test message with some parameters {a}, {b}, {c}", 100, "some string", true);
55+
}
56+
}
4657
}
4758
}

0 commit comments

Comments
 (0)