diff --git a/README.md b/README.md index e0643aa..e46641c 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,20 @@ public static class Program ### Change Log +10.0.0 + * Breaking: writeInBatches removed, all writes are now batched + * Update: update to serilog 4.0 + * Remove: removed dependance on Serilog.Sinks.PeriodicBatching, use serilog 4.0 `IBatchedLogEventSink` + +9.6.0 + * Fix: improve timezone support + +9.5.0 + * Add: use ULID for rowkey for speed and efficiency + +9.4.0 + * Fix: prevent duplicate rowkey + 9.1.0 * Add: Built-in trace and span id support diff --git a/src/Serilog.Sinks.AzureTableStorage/LoggerConfigurationAzureTableStorageExtensions.cs b/src/Serilog.Sinks.AzureTableStorage/LoggerConfigurationAzureTableStorageExtensions.cs index de3c246..3a54cd0 100644 --- a/src/Serilog.Sinks.AzureTableStorage/LoggerConfigurationAzureTableStorageExtensions.cs +++ b/src/Serilog.Sinks.AzureTableStorage/LoggerConfigurationAzureTableStorageExtensions.cs @@ -25,7 +25,6 @@ using Serilog.Formatting; using Serilog.Formatting.Json; using Serilog.Sinks.AzureTableStorage; -using Serilog.Sinks.PeriodicBatching; namespace Serilog; @@ -53,7 +52,6 @@ public static class LoggerConfigurationAzureTableStorageExtensions /// The minimum log event level required in order to write an event to the sink. /// Supplies culture-specific formatting information, or null. /// Table name that log entries will be written to. Note: Optional, setting this may impact performance - /// Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink /// The maximum number of events to post in a single batch. /// The time to wait between checking for event batches. /// The key generator used to create the PartitionKey and the RowKey for each log entry @@ -70,7 +68,6 @@ public static LoggerConfiguration AzureTableStorage( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, IFormatProvider formatProvider = null, string storageTableName = null, - bool writeInBatches = true, TimeSpan? period = null, int? batchPostingLimit = null, IKeyGenerator keyGenerator = null, @@ -92,7 +89,6 @@ public static LoggerConfiguration AzureTableStorage( restrictedToMinimumLevel: restrictedToMinimumLevel, formatProvider: formatProvider, storageTableName: storageTableName, - writeInBatches: writeInBatches, period: period, batchPostingLimit: batchPostingLimit, keyGenerator: keyGenerator, @@ -111,7 +107,6 @@ public static LoggerConfiguration AzureTableStorage( /// The minimum log event level required in order to write an event to the sink. /// Supplies culture-specific formatting information, or null. /// Table name that log entries will be written to. Note: Optional, setting this may impact performance - /// Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink /// The maximum number of events to post in a single batch. /// The time to wait between checking for event batches. /// The key generator used to create the PartitionKey and the RowKey for each log entry @@ -128,7 +123,6 @@ public static LoggerConfiguration AzureTableStorage( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, IFormatProvider formatProvider = null, string storageTableName = null, - bool writeInBatches = true, TimeSpan? period = null, int? batchPostingLimit = null, IKeyGenerator keyGenerator = null, @@ -150,7 +144,6 @@ public static LoggerConfiguration AzureTableStorage( restrictedToMinimumLevel: restrictedToMinimumLevel, formatProvider: formatProvider, storageTableName: storageTableName, - writeInBatches: writeInBatches, period: period, batchPostingLimit: batchPostingLimit, keyGenerator: keyGenerator, @@ -171,7 +164,6 @@ public static LoggerConfiguration AzureTableStorage( /// The minimum log event level required in order to write an event to the sink. /// Supplies culture-specific formatting information, or null. /// Table name that log entries will be written to. Note: Optional, setting this may impact performance - /// Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink /// The maximum number of events to post in a single batch. /// The time to wait between checking for event batches. /// The key generator used to create the PartitionKey and the RowKey for each log entry @@ -189,7 +181,6 @@ public static LoggerConfiguration AzureTableStorage( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, IFormatProvider formatProvider = null, string storageTableName = null, - bool writeInBatches = true, TimeSpan? period = null, int? batchPostingLimit = null, IKeyGenerator keyGenerator = null, @@ -214,7 +205,6 @@ public static LoggerConfiguration AzureTableStorage( restrictedToMinimumLevel: restrictedToMinimumLevel, formatProvider: formatProvider, storageTableName: storageTableName, - writeInBatches: writeInBatches, period: period, batchPostingLimit: batchPostingLimit, keyGenerator: keyGenerator, @@ -233,7 +223,6 @@ public static LoggerConfiguration AzureTableStorage( /// The minimum log event level required in order to write an event to the sink. /// Supplies culture-specific formatting information, or null. /// Table name that log entries will be written to. Note: Optional, setting this may impact performance - /// Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink; /// The maximum number of events to post in a single batch. /// The time to wait between checking for event batches. /// The key generator used to create the PartitionKey and the RowKey for each log entry @@ -251,7 +240,6 @@ public static LoggerConfiguration AzureTableStorage( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, IFormatProvider formatProvider = null, string storageTableName = null, - bool writeInBatches = true, TimeSpan? period = null, int? batchPostingLimit = null, IKeyGenerator keyGenerator = null, @@ -268,7 +256,6 @@ public static LoggerConfiguration AzureTableStorage( if (storageAccount == null) throw new ArgumentNullException(nameof(storageAccount)); - ILogEventSink sink; try { var options = new AzureTableStorageSinkOptions @@ -292,30 +279,22 @@ public static LoggerConfiguration AzureTableStorage( keyGenerator: keyGenerator, tableClientFactory: tableClientFactory); - if (writeInBatches) + var batchingOptions = new BatchingOptions { - // wrap in PeriodicBatchingSink - var batchingOptions = new PeriodicBatchingSinkOptions - { - BatchSizeLimit = batchPostingLimit ?? DefaultBatchSizeLimit, - EagerlyEmitFirstEvent = true, - Period = period ?? DefaultPeriod, - }; - - sink = new PeriodicBatchingSink(tableStorageSink, batchingOptions); - } - else - { - sink = tableStorageSink; - } + BatchSizeLimit = batchPostingLimit ?? DefaultBatchSizeLimit, + EagerlyEmitFirstEvent = true, + BufferingTimeLimit = period ?? DefaultPeriod, + }; + + return loggerConfiguration.Sink(tableStorageSink, batchingOptions, restrictedToMinimumLevel); } catch (Exception ex) { Debugging.SelfLog.WriteLine($"Error configuring AzureTableStorage: {ex}"); - sink = new LoggerConfiguration().CreateLogger(); + var sink = new LoggerConfiguration().CreateLogger(); + return loggerConfiguration.Sink(sink); } - return loggerConfiguration.Sink(sink, restrictedToMinimumLevel); } /// @@ -327,7 +306,6 @@ public static LoggerConfiguration AzureTableStorage( /// The minimum log event level required in order to write an event to the sink. /// Supplies culture-specific formatting information, or null. /// Table name that log entries will be written to. Note: Optional, setting this may impact performance - /// Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink /// The maximum number of events to post in a single batch. /// The time to wait between checking for event batches. /// The key generator used to create the PartitionKey and the RowKey for each log entry @@ -345,7 +323,6 @@ public static LoggerConfiguration AzureTableStorage( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, IFormatProvider formatProvider = null, string storageTableName = null, - bool writeInBatches = true, TimeSpan? period = null, int? batchPostingLimit = null, IKeyGenerator keyGenerator = null, @@ -373,7 +350,6 @@ public static LoggerConfiguration AzureTableStorage( restrictedToMinimumLevel: restrictedToMinimumLevel, formatProvider: formatProvider, storageTableName: storageTableName, - writeInBatches: writeInBatches, period: period, batchPostingLimit: batchPostingLimit, keyGenerator: keyGenerator, @@ -404,7 +380,6 @@ public static LoggerConfiguration AzureTableStorage( /// Supplies culture-specific formatting information, or null. /// The minimum log event level required in order to write an event to the sink. /// Table name that log entries will be written to. Note: Optional, setting this may impact performance - /// Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink /// The maximum number of events to post in a single batch. /// The time to wait between checking for event batches. /// The key generator used to create the PartitionKey and the RowKey for each log entry @@ -423,7 +398,6 @@ public static LoggerConfiguration AzureTableStorage( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, IFormatProvider formatProvider = null, string storageTableName = null, - bool writeInBatches = true, TimeSpan? period = null, int? batchPostingLimit = null, IKeyGenerator keyGenerator = null, @@ -460,7 +434,6 @@ public static LoggerConfiguration AzureTableStorage( restrictedToMinimumLevel: restrictedToMinimumLevel, formatProvider: formatProvider, storageTableName: storageTableName, - writeInBatches: writeInBatches, period: period, batchPostingLimit: batchPostingLimit, keyGenerator: keyGenerator, diff --git a/src/Serilog.Sinks.AzureTableStorage/Serilog.Sinks.AzureTableStorage.csproj b/src/Serilog.Sinks.AzureTableStorage/Serilog.Sinks.AzureTableStorage.csproj index 7a7597c..d1b8d84 100644 --- a/src/Serilog.Sinks.AzureTableStorage/Serilog.Sinks.AzureTableStorage.csproj +++ b/src/Serilog.Sinks.AzureTableStorage/Serilog.Sinks.AzureTableStorage.csproj @@ -53,8 +53,7 @@ - - + diff --git a/src/Serilog.Sinks.AzureTableStorage/Sinks/AzureTableStorage/AzureTableStorageSink.cs b/src/Serilog.Sinks.AzureTableStorage/Sinks/AzureTableStorage/AzureTableStorageSink.cs index b661347..5d0f4c5 100644 --- a/src/Serilog.Sinks.AzureTableStorage/Sinks/AzureTableStorage/AzureTableStorageSink.cs +++ b/src/Serilog.Sinks.AzureTableStorage/Sinks/AzureTableStorage/AzureTableStorageSink.cs @@ -21,14 +21,13 @@ using Serilog.Core; using Serilog.Events; -using Serilog.Sinks.PeriodicBatching; namespace Serilog.Sinks.AzureTableStorage; /// /// Writes log events as records to an Azure Table Storage table. /// -public class AzureTableStorageSink : ILogEventSink, IBatchedLogEventSink +public class AzureTableStorageSink : IBatchedLogEventSink { private readonly TableServiceClient _tableServiceClient; private readonly AzureTableStorageSinkOptions _options; @@ -71,25 +70,12 @@ public AzureTableStorageSink( _tableClientFactory = tableClientFactory ?? new DefaultTableClientFactory(); } - /// - /// Emit the provided log event to the sink. - /// - /// The log event to write. - /// - public void Emit(LogEvent logEvent) - { - var document = _documentFactory.Create(logEvent, _options, _keyGenerator); - var tableClient = _tableClientFactory.CreateTableClient(_options, _tableServiceClient); - - tableClient.AddEntity(document); - } - /// /// Emit a batch of log events, running asynchronously. /// /// The batch of events to emit. /// - public async Task EmitBatchAsync(IEnumerable batch) + public async Task EmitBatchAsync(IReadOnlyCollection batch) { // write documents in batches by partition key var documentGroups = batch @@ -116,8 +102,5 @@ public async Task EmitBatchAsync(IEnumerable batch) /// or timers (thus avoiding additional flush/shut-down complexity). /// /// - public Task OnEmptyBatchAsync() - { - return Task.CompletedTask; - } + public Task OnEmptyBatchAsync() => Task.CompletedTask; } diff --git a/test/Serilog.Sinks.AzureTableStorage.Tests/AzureTableStorageWithPropertiesSinkTests.cs b/test/Serilog.Sinks.AzureTableStorage.Tests/AzureTableStorageWithPropertiesSinkTests.cs index ef559d4..342e4b4 100644 --- a/test/Serilog.Sinks.AzureTableStorage.Tests/AzureTableStorageWithPropertiesSinkTests.cs +++ b/test/Serilog.Sinks.AzureTableStorage.Tests/AzureTableStorageWithPropertiesSinkTests.cs @@ -32,15 +32,12 @@ static async Task> TableQueryTakeDynamicAsync(TableClient tab public async Task WhenALoggerWritesToTheSinkItIsRetrievableFromTheTableWithProperties() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var exception = new ArgumentException("Some exception"); @@ -49,6 +46,8 @@ public async Task WhenALoggerWritesToTheSinkItIsRetrievableFromTheTableWithPrope logger.Information(exception, messageTemplate, "Properties", 1234, ' '); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); // Check the presence of same properties as in previous version @@ -61,6 +60,8 @@ public async Task WhenALoggerWritesToTheSinkItIsRetrievableFromTheTableWithPrope Assert.Equal("Properties", result["Properties"]); Assert.Equal(1234, result["Numbered"]); Assert.Equal(" ", result["Space"]); + + await table.DeleteAsync(); } [Fact] @@ -68,24 +69,25 @@ public async Task WhenALoggerWritesToTheSinkWithAWindowsNewlineInTheTemplateItIs { // Prompted from https://github.com/serilog/serilog-sinks-azuretablestorage/issues/10 var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); const string messageTemplate = "Line 1\r\nLine2"; logger.Information(messageTemplate); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.NotNull(result); + + await table.DeleteAsync(); } [Fact] @@ -93,24 +95,25 @@ public async Task WhenALoggerWritesToTheSinkWithALineFeedInTheTemplateItIsRetrie { // Prompted from https://github.com/serilog/serilog-sinks-azuretablestorage/issues/10 var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); const string messageTemplate = "Line 1\nLine2"; logger.Information(messageTemplate); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.NotNull(result); + + await table.DeleteAsync(); } [Fact] @@ -118,39 +121,37 @@ public async Task WhenALoggerWritesToTheSinkWithACarriageReturnInTheTemplateItIs { // Prompted from https://github.com/serilog/serilog-sinks-azuretablestorage/issues/10 var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); const string messageTemplate = "Line 1\rLine2"; logger.Information(messageTemplate); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.NotNull(result); + + await table.DeleteAsync(); } [Fact] public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForScalar() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var bytearrayValue = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 250, 251, 252, 253, 254, 255 }; @@ -174,6 +175,8 @@ public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForScalar() longValue, stringValue); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); //Assert.Equal(bytearrayValue, result.Properties["ByteArray"].BinaryValue); @@ -185,21 +188,20 @@ public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForScalar() Assert.Equal(intValue, result["Int"]); Assert.Equal(longValue, result["Long"]); Assert.Equal(stringValue, result["String"]); + + await table.DeleteAsync(); } [Fact] public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForDictionary() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var dict1 = new Dictionary{ @@ -220,34 +222,39 @@ public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForDictionary }; logger.Information("{Dictionary}", dict0); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.Equal("[(\"d1\": [(\"d1k1\": \"d1k1v1\"), (\"d1k2\": \"d1k2v2\"), (\"d1k3\": \"d1k3v3\")]), (\"d2\": [(\"d2k1\": \"d2k1v1\"), (\"d2k2\": \"d2k2v2\"), (\"d2k3\": \"d2k3v3\")])]", result["Dictionary"] as string); + + await table.DeleteAsync(); } [Fact] public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForSequence() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var seq1 = new int[] { 1, 2, 3, 4, 5 }; var seq2 = new string[] { "a", "b", "c", "d", "e" }; logger.Information("{Seq1} {Seq2}", seq1, seq2); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.Equal("[1, 2, 3, 4, 5]", result["Seq1"]); Assert.Equal("[\"a\", \"b\", \"c\", \"d\", \"e\"]", result["Seq2"]); + + await table.DeleteAsync(); } private class Struct1 @@ -272,15 +279,12 @@ private class Struct0 public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForStructure() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var struct1 = new Struct1 @@ -302,6 +306,8 @@ public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForStructure( }; logger.Information("{@Struct0}", struct0); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); #if NET472 @@ -309,64 +315,68 @@ public async Task WhenALoggerWritesToTheSinkItStoresTheCorrectTypesForStructure( #else Assert.Equal("Struct0 { Struct1Val: Struct1 { IntVal: 10, StringVal: \"ABCDE\" }, Struct2Val: Struct2 { DateTimeVal: 12/03/2014 17:37:12, DoubleVal: 3.141592653589793 } }", result["Struct0"]); #endif + + await table.DeleteAsync(); } [Fact] public async Task WhenALoggerWritesToTheSinkItAllowsStringFormatNumericPropertyNames() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var expectedResult = "Hello \"world\""; logger.Information("Hello {0}", "world"); + + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.Equal(expectedResult, result["RenderedMessage"]); + + await table.DeleteAsync(); } [Fact] public async Task WhenALoggerWritesToTheSinkItAllowsNamedAndNumericPropertyNames() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var logger = new LoggerConfiguration() .WriteTo.AzureTableStorage( storageAccount: storageAccount, - storageTableName: table.Name, - writeInBatches: false) + storageTableName: table.Name) .CreateLogger(); var name = "John Smith"; var expectedResult = "Hello \"world\" this is \"John Smith\" 1234"; logger.Information("Hello {0} this is {Name} {_1234}", "world", name, 1234); + + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); Assert.Equal(expectedResult, result["RenderedMessage"]); Assert.Equal(name, result["Name"]); Assert.Equal(1234, result["_1234"]); + + await table.DeleteAsync(); } [Fact] public async Task WhenABatchLoggerWritesToTheSinkItStoresAllTheEntries() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var options = new AzureTableStorageSinkOptions { @@ -390,15 +400,15 @@ public async Task WhenABatchLoggerWritesToTheSinkItStoresAllTheEntries() var result = await TableQueryTakeDynamicAsync(table, takeCount: 11); Assert.Equal(10, result.Count); + + await table.DeleteAsync(); } [Fact] public async Task WhenABatchLoggerWritesToTheSinkItStoresAllTheEntriesInDifferentPartitions() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var options = new AzureTableStorageSinkOptions { @@ -425,15 +435,15 @@ public async Task WhenABatchLoggerWritesToTheSinkItStoresAllTheEntriesInDifferen var result = await TableQueryTakeDynamicAsync(table, takeCount: events.Count + 1); Assert.Equal(events.Count, result.Count); + + await table.DeleteAsync(); } [Fact] public async Task WhenABatchLoggerWritesToTheSinkItStoresAllTheEntriesInLargeNumber() { var storageAccount = new TableServiceClient(DevelopmentStorageAccountConnectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); - - await table.DeleteAsync(); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); var options = new AzureTableStorageSinkOptions { @@ -457,6 +467,8 @@ public async Task WhenABatchLoggerWritesToTheSinkItStoresAllTheEntriesInLargeNum var result = await TableQueryTakeDynamicAsync(table, takeCount: 301); Assert.Equal(300, result.Count); + + await table.DeleteAsync(); } [Fact] @@ -523,9 +535,8 @@ public async Task WhenALoggerUsesASASSinkItIsRetrievableFromTheTableWithProperti string connectionString = DevelopmentStorageAccountConnectionString; string tableEndpoint = DevelopmentStorageAccountTableEndpoint; var storageAccount = new TableServiceClient(connectionString); - var table = storageAccount.GetTableClient("LogUnitTest"); + var table = storageAccount.GetTableClient($"LogUnitTest{DateTime.Now.Ticks}"); - await table.DeleteAsync(); await table.CreateIfNotExistsAsync(); var sharedAccessSignature = GetAccountSharedAccessSignature(storageAccount); @@ -543,6 +554,8 @@ public async Task WhenALoggerUsesASASSinkItIsRetrievableFromTheTableWithProperti logger.Information(exception, messageTemplate, "Properties", 1234, ' '); + logger.Dispose(); + var result = (await TableQueryTakeDynamicAsync(table, takeCount: 1)).First(); // Check the presence of same properties as in previous version @@ -555,5 +568,7 @@ public async Task WhenALoggerUsesASASSinkItIsRetrievableFromTheTableWithProperti Assert.Equal("Properties", result["Properties"]); Assert.Equal(1234, result["Numbered"]); Assert.Equal(" ", result["Space"]); + + await table.DeleteAsync(); } }