|
13 | 13 | // limitations under the License.
|
14 | 14 |
|
15 | 15 | using System;
|
| 16 | +using Microsoft.Data.SqlClient; |
16 | 17 | using Microsoft.Extensions.Configuration;
|
17 | 18 | using Serilog.Configuration;
|
18 | 19 | using Serilog.Debugging;
|
@@ -167,6 +168,85 @@ internal static LoggerConfiguration MSSqlServerInternal(
|
167 | 168 | return loggerConfiguration.Sink(periodicBatchingSink, restrictedToMinimumLevel, sinkOptions?.LevelSwitch);
|
168 | 169 | }
|
169 | 170 |
|
| 171 | + /// <summary> |
| 172 | + /// Adds a sink that writes log events to a table in a MSSqlServer database. |
| 173 | + /// Create a database and execute the table creation script found here |
| 174 | + /// https://gist.github.com/mivano/10429656 |
| 175 | + /// or use the autoCreateSqlTable option. |
| 176 | + /// </summary> |
| 177 | + /// <param name="loggerConfiguration">The logger configuration.</param> |
| 178 | + /// <param name="sqlConnectionFactory">A function to initialize a connection to the database where to store the events.</param> |
| 179 | + /// <param name="initialCatalog">The initial catalog within the database (used if AutoCreateSqlDatabase is enabled).</param> |
| 180 | + /// <param name="sinkOptions">Supplies additional settings for the sink</param> |
| 181 | + /// <param name="sinkOptionsSection">A config section defining additional settings for the sink</param> |
| 182 | + /// <param name="appConfiguration">Additional application-level configuration. Required if connectionString is a name.</param> |
| 183 | + /// <param name="restrictedToMinimumLevel">The minimum level for events passed through the sink. Ignored when LevelSwitch in <paramref name="sinkOptions"/> is specified.</param> |
| 184 | + /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param> |
| 185 | + /// <param name="columnOptions">An externally-modified group of column settings</param> |
| 186 | + /// <param name="columnOptionsSection">A config section defining various column settings</param> |
| 187 | + /// <param name="logEventFormatter">Supplies custom formatter for the LogEvent column, or null</param> |
| 188 | + /// <returns>Logger configuration, allowing configuration to continue.</returns> |
| 189 | + /// <exception cref="ArgumentNullException">A required parameter is null.</exception> |
| 190 | + public static LoggerConfiguration MSSqlServer( |
| 191 | + this LoggerSinkConfiguration loggerConfiguration, |
| 192 | + Func<SqlConnection> sqlConnectionFactory, |
| 193 | + string initialCatalog, |
| 194 | + MSSqlServerSinkOptions sinkOptions = null, |
| 195 | + IConfigurationSection sinkOptionsSection = null, |
| 196 | + IConfiguration appConfiguration = null, |
| 197 | + LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, |
| 198 | + IFormatProvider formatProvider = null, |
| 199 | + ColumnOptions columnOptions = null, |
| 200 | + IConfigurationSection columnOptionsSection = null, |
| 201 | + ITextFormatter logEventFormatter = null) => |
| 202 | + loggerConfiguration.MSSqlServerInternal( |
| 203 | + sqlConnectionFactory: sqlConnectionFactory, |
| 204 | + initialCatalog: initialCatalog, |
| 205 | + sinkOptions: sinkOptions, |
| 206 | + sinkOptionsSection: sinkOptionsSection, |
| 207 | + appConfiguration: appConfiguration, |
| 208 | + restrictedToMinimumLevel: restrictedToMinimumLevel, |
| 209 | + formatProvider: formatProvider, |
| 210 | + columnOptions: columnOptions, |
| 211 | + columnOptionsSection: columnOptionsSection, |
| 212 | + logEventFormatter: logEventFormatter, |
| 213 | + applySystemConfiguration: new ApplySystemConfiguration(), |
| 214 | + applyMicrosoftExtensionsConfiguration: new ApplyMicrosoftExtensionsConfiguration(), |
| 215 | + sinkFactory: new MSSqlServerSinkFactory(), |
| 216 | + batchingSinkFactory: new PeriodicBatchingSinkFactory()); |
| 217 | + |
| 218 | + // Internal overload with parameters used by tests to override the config section and inject mocks |
| 219 | + internal static LoggerConfiguration MSSqlServerInternal( |
| 220 | + this LoggerSinkConfiguration loggerConfiguration, |
| 221 | + Func<SqlConnection> sqlConnectionFactory, |
| 222 | + string initialCatalog, |
| 223 | + MSSqlServerSinkOptions sinkOptions, |
| 224 | + IConfigurationSection sinkOptionsSection, |
| 225 | + IConfiguration appConfiguration, |
| 226 | + LogEventLevel restrictedToMinimumLevel, |
| 227 | + IFormatProvider formatProvider, |
| 228 | + ColumnOptions columnOptions, |
| 229 | + IConfigurationSection columnOptionsSection, |
| 230 | + ITextFormatter logEventFormatter, |
| 231 | + IApplySystemConfiguration applySystemConfiguration, |
| 232 | + IApplyMicrosoftExtensionsConfiguration applyMicrosoftExtensionsConfiguration, |
| 233 | + IMSSqlServerSinkFactory sinkFactory, |
| 234 | + IPeriodicBatchingSinkFactory batchingSinkFactory) |
| 235 | + { |
| 236 | + if (loggerConfiguration == null) |
| 237 | + throw new ArgumentNullException(nameof(loggerConfiguration)); |
| 238 | + |
| 239 | + ReadConfiguration(ref sinkOptions, sinkOptionsSection, appConfiguration, |
| 240 | + ref columnOptions, columnOptionsSection, applySystemConfiguration, applyMicrosoftExtensionsConfiguration); |
| 241 | + |
| 242 | + var sink = sinkFactory.Create(sqlConnectionFactory, initialCatalog, sinkOptions, formatProvider, columnOptions, logEventFormatter); |
| 243 | + |
| 244 | + var periodicBatchingSink = batchingSinkFactory.Create(sink, sinkOptions); |
| 245 | + |
| 246 | + return loggerConfiguration.Sink(periodicBatchingSink, restrictedToMinimumLevel, sinkOptions?.LevelSwitch); |
| 247 | + } |
| 248 | + |
| 249 | + |
170 | 250 | /// <summary>
|
171 | 251 | /// Adds a sink that writes log events to a table in a MSSqlServer database.
|
172 | 252 | ///
|
@@ -313,6 +393,40 @@ private static void ReadConfiguration(
|
313 | 393 | connectionString = applyMicrosoftExtensionsConfiguration.GetConnectionString(connectionString, appConfiguration);
|
314 | 394 | }
|
315 | 395 |
|
| 396 | + if (columnOptionsSection != null) |
| 397 | + { |
| 398 | + columnOptions = applyMicrosoftExtensionsConfiguration.ConfigureColumnOptions(columnOptions, columnOptionsSection); |
| 399 | + } |
| 400 | + |
| 401 | + if (sinkOptionsSection != null) |
| 402 | + { |
| 403 | + sinkOptions = applyMicrosoftExtensionsConfiguration.ConfigureSinkOptions(sinkOptions, sinkOptionsSection); |
| 404 | + } |
| 405 | + } |
| 406 | + |
| 407 | + private static void ReadConfiguration( |
| 408 | + ref MSSqlServerSinkOptions sinkOptions, |
| 409 | + IConfigurationSection sinkOptionsSection, |
| 410 | + IConfiguration appConfiguration, |
| 411 | + ref ColumnOptions columnOptions, |
| 412 | + IConfigurationSection columnOptionsSection, |
| 413 | + IApplySystemConfiguration applySystemConfiguration, |
| 414 | + IApplyMicrosoftExtensionsConfiguration applyMicrosoftExtensionsConfiguration) |
| 415 | + { |
| 416 | + sinkOptions = sinkOptions ?? new MSSqlServerSinkOptions(); |
| 417 | + columnOptions = columnOptions ?? new ColumnOptions(); |
| 418 | + |
| 419 | + var serviceConfigSection = applySystemConfiguration.GetSinkConfigurationSection(AppConfigSectionName); |
| 420 | + if (serviceConfigSection != null) |
| 421 | + { |
| 422 | + columnOptions = applySystemConfiguration.ConfigureColumnOptions(serviceConfigSection, columnOptions); |
| 423 | + sinkOptions = applySystemConfiguration.ConfigureSinkOptions(serviceConfigSection, sinkOptions); |
| 424 | + |
| 425 | + if (appConfiguration != null || columnOptionsSection != null || sinkOptionsSection != null) |
| 426 | + SelfLog.WriteLine("Warning: Both System.Configuration (app.config or web.config) and Microsoft.Extensions.Configuration are being applied to the MSSQLServer sink."); |
| 427 | + } |
| 428 | + |
| 429 | + |
316 | 430 | if (columnOptionsSection != null)
|
317 | 431 | {
|
318 | 432 | columnOptions = applyMicrosoftExtensionsConfiguration.ConfigureColumnOptions(columnOptions, columnOptionsSection);
|
|
0 commit comments