Skip to content

Commit bdbd684

Browse files
committed
Fixed issue #191: Added option EagerlyEmitFirstEvent by implementing new new PeriodicBatchingSink API.
* Implement new composition based api of PeriodicBatchingSink. * Added SinkOptions.EagerlyEmitFirstEvent to control if first batch should be written as soon as possible regardless of period and number of events. * Removed default parameters on internal config extension methods like MSSqlServerInternal(): they can lead to subtle runtime errors and are not useful in this place.
1 parent 727e9a9 commit bdbd684

25 files changed

+625
-126
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ Basic settings of the sink are configured using the properties in a `SinkOptions
244244
* `AutoCreateSqlTable`
245245
* `BatchPostingLimit`
246246
* `BatchPeriod`
247+
* `EagerlyEmitFirstEvent`
247248
* `UseAzureManagedIdentity`
248249
* `AzureServiceTokenProviderResource`
249250

@@ -267,7 +268,12 @@ This setting is not used by the audit sink as it writes each event immediately a
267268
### BatchPeriod
268269

269270
Specifies the interval in which the non-audit sink writes a batch of log events to the database. It defaults to 5 seconds.
270-
Just like `BatchPostingLimit`, this setting is not used by the audit sink as it is not a batch based sink.
271+
This setting is not used by the audit sink as it writes each event immediately and not in a batched manner.
272+
273+
### EagerlyEmitFirstEvent
274+
275+
A Flag to eagerly write a batch to the database containing the first received event regardless of `BatchPostingLimit` or `BatchPeriod`. It defaults to ture.
276+
This setting is not used by the audit sink as it writes each event immediately and not in a batched manner.
271277

272278
### UseAzureManagedIdentity
273279

sample/AppConfigDemo/App.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
<BatchPostingLimit Value="13" />
1212
<BatchPeriod Value="00:00:15" />
13+
<EagerlyEmitFirstEvent Value="true" />
1314

1415
<AddStandardColumns>
1516
<add Name="LogEvent" />

sample/CombinedConfigDemo/CombinedConfigDemo.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
<ItemGroup>
1515
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" />
16-
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
1716
</ItemGroup>
1817

1918
<ItemGroup>

sample/CombinedConfigDemo/Program.cs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Threading;
23
using Microsoft.Extensions.Configuration;
34
using Serilog;
45
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Options;
@@ -22,35 +23,37 @@ public static void Main()
2223
var columnOptionsSection = configuration.GetSection("Serilog:ColumnOptions");
2324
var sinkOptionsSection = configuration.GetSection("Serilog:SinkOptions");
2425

25-
Serilog.Debugging.SelfLog.Enable(m => Debug.WriteLine(m));
26+
// Legacy interace - do not use this anymore
27+
//Log.Logger = new LoggerConfiguration()
28+
// .WriteTo.MSSqlServer(
29+
// connectionString: _connectionStringName,
30+
// tableName: _tableName,
31+
// appConfiguration: configuration,
32+
// autoCreateSqlTable: true,
33+
// columnOptionsSection: columnOptionsSection,
34+
// schemaName: _schemaName)
35+
// .CreateLogger();
2636

2737
// New SinkOptions based interface
28-
using (var logger = new LoggerConfiguration()
29-
.WriteTo.Console()
38+
Log.Logger = new LoggerConfiguration()
3039
.WriteTo.MSSqlServer(
3140
connectionString: _connectionStringName,
3241
sinkOptions: new SinkOptions
3342
{
3443
TableName = _tableName,
3544
SchemaName = _schemaName,
36-
AutoCreateSqlTable = false
45+
AutoCreateSqlTable = true
3746
},
3847
sinkOptionsSection: sinkOptionsSection,
3948
appConfiguration: configuration,
4049
columnOptionsSection: columnOptionsSection)
41-
.CreateLogger())
42-
{
43-
logger.Information("Log 1");
44-
logger.Information("Log 2");
45-
logger.Information("Log 3");
46-
logger.Information("Log 4");
47-
logger.Information("Log 5");
48-
logger.Information("Log 6");
49-
logger.Information("Log 7");
50-
logger.Information("Log 8");
51-
logger.Information("Log 9");
52-
logger.Information("Log 10");
53-
}
50+
.CreateLogger();
51+
52+
Log.Information("Hello {Name} from thread {ThreadId}", Environment.GetEnvironmentVariable("USERNAME"), Thread.CurrentThread.ManagedThreadId);
53+
54+
Log.Warning("No coins remain at position {@Position}", new { Lat = 25, Long = 134 });
55+
56+
Log.CloseAndFlush();
5457
}
5558
}
5659
}

sample/CombinedConfigDemo/appsettings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
},
1212
"Serilog": {
1313
"SinkOptions": {
14-
"batchPostingLimit": 500
14+
"batchPostingLimit": 5,
15+
"batchPeriod": "00:00:15",
16+
"eagerlyEmitFirstEvent": true
1517
},
1618
"ColumnOptions": {
1719
"addStandardColumns": [ "LogEvent" ],

src/Serilog.Sinks.MSSqlServer/Configuration/Extensions/Hybrid/LoggerConfigurationMSSqlServerExtensions.cs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -136,23 +136,25 @@ public static LoggerConfiguration MSSqlServer(
136136
logEventFormatter: logEventFormatter,
137137
applySystemConfiguration: new ApplySystemConfiguration(),
138138
applyMicrosoftExtensionsConfiguration: new ApplyMicrosoftExtensionsConfiguration(),
139-
sinkFactory: new MSSqlServerSinkFactory());
139+
sinkFactory: new MSSqlServerSinkFactory(),
140+
batchingSinkFactory: new PeriodicBatchingSinkFactory());
140141

141142
// Internal overload with parameters used by tests to override the config section and inject mocks
142143
internal static LoggerConfiguration MSSqlServerInternal(
143144
this LoggerSinkConfiguration loggerConfiguration,
144145
string connectionString,
145-
SinkOptions sinkOptions = null,
146-
IConfigurationSection sinkOptionsSection = null,
147-
IConfiguration appConfiguration = null,
148-
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
149-
IFormatProvider formatProvider = null,
150-
ColumnOptions columnOptions = null,
151-
IConfigurationSection columnOptionsSection = null,
152-
ITextFormatter logEventFormatter = null,
153-
IApplySystemConfiguration applySystemConfiguration = null,
154-
IApplyMicrosoftExtensionsConfiguration applyMicrosoftExtensionsConfiguration = null,
155-
IMSSqlServerSinkFactory sinkFactory = null)
146+
SinkOptions sinkOptions,
147+
IConfigurationSection sinkOptionsSection,
148+
IConfiguration appConfiguration,
149+
LogEventLevel restrictedToMinimumLevel,
150+
IFormatProvider formatProvider,
151+
ColumnOptions columnOptions,
152+
IConfigurationSection columnOptionsSection,
153+
ITextFormatter logEventFormatter,
154+
IApplySystemConfiguration applySystemConfiguration,
155+
IApplyMicrosoftExtensionsConfiguration applyMicrosoftExtensionsConfiguration,
156+
IMSSqlServerSinkFactory sinkFactory,
157+
IPeriodicBatchingSinkFactory batchingSinkFactory)
156158
{
157159
if (loggerConfiguration == null)
158160
throw new ArgumentNullException(nameof(loggerConfiguration));
@@ -162,7 +164,9 @@ internal static LoggerConfiguration MSSqlServerInternal(
162164

163165
var sink = sinkFactory.Create(connectionString, sinkOptions, formatProvider, columnOptions, logEventFormatter);
164166

165-
return loggerConfiguration.Sink(sink, restrictedToMinimumLevel);
167+
var periodicBatchingSink = batchingSinkFactory.Create(sink, sinkOptions);
168+
169+
return loggerConfiguration.Sink(periodicBatchingSink, restrictedToMinimumLevel);
166170
}
167171

168172
/// <summary>
@@ -259,17 +263,17 @@ public static LoggerConfiguration MSSqlServer(
259263
internal static LoggerConfiguration MSSqlServerInternal(
260264
this LoggerAuditSinkConfiguration loggerAuditSinkConfiguration,
261265
string connectionString,
262-
SinkOptions sinkOptions = null,
263-
IConfigurationSection sinkOptionsSection = null,
264-
IConfiguration appConfiguration = null,
265-
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
266-
IFormatProvider formatProvider = null,
267-
ColumnOptions columnOptions = null,
268-
IConfigurationSection columnOptionsSection = null,
269-
ITextFormatter logEventFormatter = null,
270-
IApplySystemConfiguration applySystemConfiguration = null,
271-
IApplyMicrosoftExtensionsConfiguration applyMicrosoftExtensionsConfiguration = null,
272-
IMSSqlServerAuditSinkFactory auditSinkFactory = null)
266+
SinkOptions sinkOptions,
267+
IConfigurationSection sinkOptionsSection,
268+
IConfiguration appConfiguration,
269+
LogEventLevel restrictedToMinimumLevel,
270+
IFormatProvider formatProvider,
271+
ColumnOptions columnOptions,
272+
IConfigurationSection columnOptionsSection,
273+
ITextFormatter logEventFormatter,
274+
IApplySystemConfiguration applySystemConfiguration,
275+
IApplyMicrosoftExtensionsConfiguration applyMicrosoftExtensionsConfiguration,
276+
IMSSqlServerAuditSinkFactory auditSinkFactory)
273277
{
274278
if (loggerAuditSinkConfiguration == null)
275279
throw new ArgumentNullException(nameof(loggerAuditSinkConfiguration));

src/Serilog.Sinks.MSSqlServer/Configuration/Extensions/Microsoft.Extensions.Configuration/LoggerConfigurationMSSqlServerExtensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ public static LoggerConfiguration MSSqlServer(
126126
IMSSqlServerSinkFactory sinkFactory = new MSSqlServerSinkFactory();
127127
var sink = sinkFactory.Create(connectionString, sinkOptions, formatProvider, columnOptions, logEventFormatter);
128128

129-
return loggerConfiguration.Sink(sink, restrictedToMinimumLevel);
129+
IPeriodicBatchingSinkFactory periodicBatchingSinkFactory = new PeriodicBatchingSinkFactory();
130+
var periodicBatchingSink = periodicBatchingSinkFactory.Create(sink, sinkOptions);
131+
132+
return loggerConfiguration.Sink(periodicBatchingSink, restrictedToMinimumLevel);
130133
}
131134

132135
/// <summary>

src/Serilog.Sinks.MSSqlServer/Configuration/Extensions/System.Configuration/LoggerConfigurationMSSqlServerExtensions.cs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,22 @@ public static LoggerConfiguration MSSqlServer(
116116
columnOptions: columnOptions,
117117
logEventFormatter: logEventFormatter,
118118
applySystemConfiguration: new ApplySystemConfiguration(),
119-
sinkFactory: new MSSqlServerSinkFactory());
119+
sinkFactory: new MSSqlServerSinkFactory(),
120+
periodicBatchingSinkFactory: new PeriodicBatchingSinkFactory());
120121

121122
// Internal overload with parameters used by tests to override the config section and inject mocks
122123
internal static LoggerConfiguration MSSqlServerInternal(
123124
this LoggerSinkConfiguration loggerConfiguration,
124125
string configSectionName,
125126
string connectionString,
126-
SinkOptions sinkOptions = null,
127-
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
128-
IFormatProvider formatProvider = null,
129-
ColumnOptions columnOptions = null,
130-
ITextFormatter logEventFormatter = null,
131-
IApplySystemConfiguration applySystemConfiguration = null,
132-
IMSSqlServerSinkFactory sinkFactory = null)
127+
SinkOptions sinkOptions,
128+
LogEventLevel restrictedToMinimumLevel,
129+
IFormatProvider formatProvider,
130+
ColumnOptions columnOptions,
131+
ITextFormatter logEventFormatter,
132+
IApplySystemConfiguration applySystemConfiguration,
133+
IMSSqlServerSinkFactory sinkFactory,
134+
IPeriodicBatchingSinkFactory periodicBatchingSinkFactory)
133135
{
134136
if (loggerConfiguration == null)
135137
throw new ArgumentNullException(nameof(loggerConfiguration));
@@ -138,7 +140,9 @@ internal static LoggerConfiguration MSSqlServerInternal(
138140

139141
var sink = sinkFactory.Create(connectionString, sinkOptions, formatProvider, columnOptions, logEventFormatter);
140142

141-
return loggerConfiguration.Sink(sink, restrictedToMinimumLevel);
143+
var periodicBatchingSink = periodicBatchingSinkFactory.Create(sink, sinkOptions);
144+
145+
return loggerConfiguration.Sink(periodicBatchingSink, restrictedToMinimumLevel);
142146
}
143147

144148
/// <summary>
@@ -226,13 +230,13 @@ internal static LoggerConfiguration MSSqlServerInternal(
226230
this LoggerAuditSinkConfiguration loggerAuditSinkConfiguration,
227231
string configSectionName,
228232
string connectionString,
229-
SinkOptions sinkOptions = null,
230-
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
231-
IFormatProvider formatProvider = null,
232-
ColumnOptions columnOptions = null,
233-
ITextFormatter logEventFormatter = null,
234-
IApplySystemConfiguration applySystemConfiguration = null,
235-
IMSSqlServerAuditSinkFactory auditSinkFactory = null)
233+
SinkOptions sinkOptions,
234+
LogEventLevel restrictedToMinimumLevel,
235+
IFormatProvider formatProvider,
236+
ColumnOptions columnOptions,
237+
ITextFormatter logEventFormatter,
238+
IApplySystemConfiguration applySystemConfiguration,
239+
IMSSqlServerAuditSinkFactory auditSinkFactory)
236240
{
237241
if (loggerAuditSinkConfiguration == null)
238242
throw new ArgumentNullException(nameof(loggerAuditSinkConfiguration));

src/Serilog.Sinks.MSSqlServer/Configuration/Factories/IMSSqlServerAuditSinkFactory.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
using System;
2+
using Serilog.Core;
23
using Serilog.Formatting;
34
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Options;
45

56
namespace Serilog.Sinks.MSSqlServer.Configuration.Factories
67
{
78
internal interface IMSSqlServerAuditSinkFactory
89
{
9-
MSSqlServerAuditSink Create(
10+
ILogEventSink Create(
1011
string connectionString,
1112
SinkOptions sinkOptions,
1213
IFormatProvider formatProvider,

src/Serilog.Sinks.MSSqlServer/Configuration/Factories/IMSSqlServerSinkFactory.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
using System;
22
using Serilog.Formatting;
33
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Options;
4+
using Serilog.Sinks.PeriodicBatching;
45

56
namespace Serilog.Sinks.MSSqlServer.Configuration.Factories
67
{
78
internal interface IMSSqlServerSinkFactory
89
{
9-
MSSqlServerSink Create(
10+
IBatchedLogEventSink Create(
1011
string connectionString,
1112
SinkOptions sinkOptions,
1213
IFormatProvider formatProvider,

0 commit comments

Comments
 (0)