From c5a8c1cf27d17c35789c645635274d7b8cdc97fc Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Mon, 11 Nov 2019 07:41:41 -0800 Subject: [PATCH] Another try at simple logging... Fixes #16200 Fixes #1199 Examples: Log to the Console: ```C# protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseMyProvider("...") .LogTo(Console.WriteLine); ``` Log to the Console for a given level: ```C# protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseMyProvider("...") .LogTo(Console.WriteLine, LogLevel.Information)); ``` Log to the Console for specific events: ```C# protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseMyProvider("...") .LogTo(Console.WriteLine, new[] { CoreEventId.ContextInitialized, CoreEventId.ContextDisposed })); ``` Log to the Console for specific categories: ```C# protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseMyProvider("...") .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Infrastructure.Name, DbLoggerCategory.Update.Name })); ``` Log to the Console with custom filter: ```C# protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseMyProvider("...") .LogTo(Console.WriteLine, (e, l) => e == CoreEventId.SaveChangesCompleted))); ``` Log to the Console for events in specific categories and a given level formatted as a single line using UTC timestamps: ```C# protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseMyProvider("...") .LogTo( Console.WriteLine, new[] { DbLoggerCategory.Infrastructure.Name, DbLoggerCategory.Update.Name }, LogLevel.Information, SimpleLoggerFormatOptions.SingleLine | SimpleLoggerFormatOptions.DefaultWithUtcTime | )); ``` --- .../Internal/CosmosLoggerExtensions.cs | 3 - .../Query/Internal/SqlParameterExpression.cs | 2 +- .../DesignTimeServiceCollectionExtensions.cs | 1 + .../Internal/InMemoryLoggerExtensions.cs | 41 +- .../Diagnostics/RelationalLoggerExtensions.cs | 1122 ++++++-------- ...elationalCompiledQueryCacheKeyGenerator.cs | 2 +- .../Query/SqlExpressions/ColumnExpression.cs | 2 +- .../Query/SqlExpressions/SelectExpression.cs | 2 +- .../SqlExpressions/SqlParameterExpression.cs | 2 +- .../Query/SqlExpressions/TableExpression.cs | 2 +- .../Internal/SqlServerLoggerExtensions.cs | 148 +- .../Internal/SqliteLoggerExtensions.cs | 123 +- .../Internal/InternalEntityEntry.cs | 4 +- src/EFCore/DbContextOptionsBuilder.cs | 206 +++ src/EFCore/DbContextOptionsBuilder`.cs | 136 ++ src/EFCore/DbFunctions.cs | 2 +- .../Diagnostics/CoreLoggerExtensions.cs | 1353 ++++++++--------- .../DiagnosticsLoggerExtensions.cs | 128 ++ src/EFCore/Diagnostics/EventData.cs | 5 + src/EFCore/Diagnostics/EventDefinition.cs | 6 +- src/EFCore/Diagnostics/EventDefinitionBase.cs | 18 +- src/EFCore/Diagnostics/EventDefinition`.cs | 4 +- src/EFCore/Diagnostics/EventDefinition``.cs | 4 +- src/EFCore/Diagnostics/EventDefinition```.cs | 4 +- src/EFCore/Diagnostics/EventDefinition````.cs | 4 +- .../Diagnostics/EventDefinition`````.cs | 4 +- .../Diagnostics/EventDefinition``````.cs | 4 +- .../Diagnostics/FallbackEventDefinition.cs | 4 +- src/EFCore/Diagnostics/IDiagnosticsLogger.cs | 10 + src/EFCore/Diagnostics/IDiagnosticsLogger`.cs | 4 - src/EFCore/Diagnostics/ISimpleLogger.cs | 39 + .../Diagnostics/Internal/NullSimpleLogger.cs | 34 + src/EFCore/Diagnostics/SimpleLogger.cs | 136 ++ .../Diagnostics/SimpleLoggerFormatOptions.cs | 73 + .../Infrastructure/CoreOptionsExtension.cs | 22 + .../EntityFrameworkServicesBuilder.cs | 3 + src/EFCore/Internal/DiagnosticsLogger.cs | 10 + src/EFCore/Internal/ServiceProviderCache.cs | 4 +- .../Conventions/ForeignKeyIndexConvention.cs | 2 +- .../Internal/EntityTypePathComparer.cs | 7 +- .../Metadata/Internal/PropertyListComparer.cs | 5 +- .../Query/CompiledQueryCacheKeyGenerator.cs | 2 +- .../InMemoryTransactionManagerTest.cs | 4 +- .../ApiConsistencyTest.cs | 15 +- .../Storage/RelationalCommandTest.cs | 12 +- .../RelationalTransactionExtensionsTest.cs | 4 +- .../TestUtilities/FakeDiagnosticsLogger.cs | 3 + .../FakeProvider/FakeRelationalConnection.cs | 7 +- .../TestUtilities/TestLogger.cs | 2 + .../TestUtilities/TestLoggerBase.cs | 3 + .../TestUtilities/TestLogger`.cs | 1 - .../TestUtilities/TestSimpleLogger.cs | 22 + .../SqlServerDatabaseModelFactoryTest.cs | 4 +- .../TestUtilities/SqlServerDatabaseCleaner.cs | 4 +- .../SqlServerConnectionTest.cs | 7 +- .../SqliteDatabaseModelFactoryTest.cs | 6 +- .../TestUtilities/SqliteDatabaseCleaner.cs | 1 + test/EFCore.Tests/ApiConsistencyTest.cs | 17 +- test/EFCore.Tests/ApiConsistencyTestBase.cs | 15 +- .../Infrastructure/DiagnosticsLoggerTest.cs | 7 +- .../Infrastructure/EventIdTestBase.cs | 7 + .../Infrastructure/ModelValidatorTestBase.cs | 7 +- ...reignKeyPropertyDiscoveryConventionTest.cs | 3 +- .../Conventions/KeyDiscoveryConventionTest.cs | 3 +- .../NavigationAttributeConventionTest.cs | 3 +- .../NonNullableNavigationConventionTest.cs | 3 +- .../RelationshipDiscoveryConventionTest.cs | 3 +- .../ModelBuilding/ModelBuilderTestBase.cs | 7 +- test/EFCore.Tests/SimpleLoggerTests.cs | 470 ++++++ 69 files changed, 2586 insertions(+), 1741 deletions(-) create mode 100644 src/EFCore/Diagnostics/DiagnosticsLoggerExtensions.cs create mode 100644 src/EFCore/Diagnostics/ISimpleLogger.cs create mode 100644 src/EFCore/Diagnostics/Internal/NullSimpleLogger.cs create mode 100644 src/EFCore/Diagnostics/SimpleLogger.cs create mode 100644 src/EFCore/Diagnostics/SimpleLoggerFormatOptions.cs create mode 100644 test/EFCore.Specification.Tests/TestUtilities/TestSimpleLogger.cs create mode 100644 test/EFCore.Tests/SimpleLoggerTests.cs diff --git a/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs b/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs index cb9074f3ccf..9a3803ab4cf 100644 --- a/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs +++ b/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs @@ -44,11 +44,8 @@ public static void ExecutingSqlQuery( CoreEventId.ProviderBaseId, "Executing Sql Query [Parameters=[{parameters}]]{newLine}{commandText}")); - var warningBehavior = definition.GetLogBehavior(diagnosticsLogger); - definition.Log( diagnosticsLogger, - warningBehavior, FormatParameters(cosmosSqlQuery.Parameters), Environment.NewLine, cosmosSqlQuery.Query); diff --git a/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs b/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs index 65b8c8b5817..1f84980a945 100644 --- a/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs @@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public class SqlParameterExpression : SqlExpression + public sealed class SqlParameterExpression : SqlExpression { private readonly ParameterExpression _parameterExpression; diff --git a/src/EFCore.Design/Design/DesignTimeServiceCollectionExtensions.cs b/src/EFCore.Design/Design/DesignTimeServiceCollectionExtensions.cs index e5cd06cdedd..b373354fc78 100644 --- a/src/EFCore.Design/Design/DesignTimeServiceCollectionExtensions.cs +++ b/src/EFCore.Design/Design/DesignTimeServiceCollectionExtensions.cs @@ -81,6 +81,7 @@ public static IServiceCollection AddEntityFrameworkDesignTimeServices( .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() .AddTransient() .AddTransient() .AddTransient() diff --git a/src/EFCore.InMemory/Diagnostics/Internal/InMemoryLoggerExtensions.cs b/src/EFCore.InMemory/Diagnostics/Internal/InMemoryLoggerExtensions.cs index f808e139ace..d611c88bee5 100644 --- a/src/EFCore.InMemory/Diagnostics/Internal/InMemoryLoggerExtensions.cs +++ b/src/EFCore.InMemory/Diagnostics/Internal/InMemoryLoggerExtensions.cs @@ -28,19 +28,18 @@ public static void TransactionIgnoredWarning( { var definition = InMemoryResources.LogTransactionsNotSupported(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new EventData( - definition, - (d, _) => ((EventDefinition)d).GenerateMessage())); + var eventData = new EventData( + definition, + (d, _) => ((EventDefinition)d).GenerateMessage()); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -57,24 +56,20 @@ public static void ChangesSaved( { var definition = InMemoryResources.LogSavedChanges(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - rowsAffected); + definition.Log(diagnostics, rowsAffected); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new SaveChangesEventData( - definition, - ChangesSaved, - entries, - rowsAffected)); + var eventData = new SaveChangesEventData( + definition, + ChangesSaved, + entries, + rowsAffected); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs index 3a8e316397d..db3b5c64b4d 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs @@ -62,11 +62,8 @@ public static InterceptionResult CommandCreating( LogCommandCreating(diagnostics, definition, commandMethod); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandCreating( diagnostics, @@ -78,7 +75,8 @@ public static InterceptionResult CommandCreating( false, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -99,7 +97,8 @@ private static CommandCorrelatedEventData BroadcastCommandCreating( bool async, DateTimeOffset startTime, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new CommandCorrelatedEventData( definition, @@ -112,10 +111,7 @@ private static CommandCorrelatedEventData BroadcastCommandCreating( async, startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -125,10 +121,9 @@ private static void LogCommandCreating( EventDefinition definition, DbCommandMethod commandMethod) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior, commandMethod.ToString()); + definition.Log(diagnostics, commandMethod.ToString()); } } @@ -167,11 +162,8 @@ public static DbCommand CommandCreated( LogCommandCreated(diagnostics, definition, commandMethod, duration); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandCreated( diagnostics, @@ -185,7 +177,8 @@ public static DbCommand CommandCreated( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -208,7 +201,8 @@ private static CommandEndEventData BroadcastCommandCreated( DateTimeOffset startTime, TimeSpan duration, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new CommandEndEventData( definition, @@ -224,10 +218,7 @@ private static CommandEndEventData BroadcastCommandCreated( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -238,10 +229,9 @@ private static void LogCommandCreated( DbCommandMethod commandMethod, TimeSpan duration) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior, commandMethod.ToString(), (int)duration.TotalMilliseconds); + definition.Log(diagnostics, commandMethod.ToString(), (int)duration.TotalMilliseconds); } } @@ -276,11 +266,8 @@ public static InterceptionResult CommandReaderExecuting( LogCommandExecuting(diagnostics, command, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuting( diagnostics, @@ -293,7 +280,8 @@ public static InterceptionResult CommandReaderExecuting( false, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -328,11 +316,8 @@ public static InterceptionResult CommandScalarExecuting( LogCommandExecuting(diagnostics, command, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuting( diagnostics, @@ -345,7 +330,8 @@ public static InterceptionResult CommandScalarExecuting( false, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -380,11 +366,8 @@ public static InterceptionResult CommandNonQueryExecuting( LogCommandExecuting(diagnostics, command, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuting( diagnostics, @@ -397,7 +380,8 @@ public static InterceptionResult CommandNonQueryExecuting( false, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -434,11 +418,8 @@ public static Task> CommandReaderExecutingAsync LogCommandExecuting(diagnostics, command, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuting( diagnostics, @@ -451,7 +432,8 @@ public static Task> CommandReaderExecutingAsync true, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -488,11 +470,8 @@ public static Task> CommandScalarExecutingAsync( LogCommandExecuting(diagnostics, command, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuting( diagnostics, @@ -505,7 +484,8 @@ public static Task> CommandScalarExecutingAsync( true, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -542,11 +522,8 @@ public static Task> CommandNonQueryExecutingAsync( LogCommandExecuting(diagnostics, command, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuting( diagnostics, @@ -559,7 +536,8 @@ public static Task> CommandNonQueryExecutingAsync( true, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -581,7 +559,8 @@ private static CommandEventData BroadcastCommandExecuting( bool async, DateTimeOffset startTime, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new CommandEventData( definition, @@ -596,12 +575,7 @@ private static CommandEventData BroadcastCommandExecuting( ShouldLogParameterValues(diagnostics, command), startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -611,12 +585,10 @@ private static void LogCommandExecuting( DbCommand command, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, command.Parameters.FormatParameters(ShouldLogParameterValues(diagnostics, command)), command.CommandType, command.CommandTimeout, @@ -671,11 +643,8 @@ public static DbDataReader CommandReaderExecuted( LogCommandExecuted(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuted( diagnostics, @@ -690,7 +659,8 @@ public static DbDataReader CommandReaderExecuted( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -729,11 +699,8 @@ public static object CommandScalarExecuted( LogCommandExecuted(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuted( diagnostics, @@ -748,7 +715,8 @@ public static object CommandScalarExecuted( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -787,11 +755,8 @@ public static int CommandNonQueryExecuted( LogCommandExecuted(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuted( diagnostics, @@ -806,7 +771,8 @@ public static int CommandNonQueryExecuted( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -847,11 +813,8 @@ public static Task CommandReaderExecutedAsync( LogCommandExecuted(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuted( diagnostics, @@ -866,7 +829,8 @@ public static Task CommandReaderExecutedAsync( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -907,11 +871,8 @@ public static Task CommandScalarExecutedAsync( LogCommandExecuted(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuted( diagnostics, @@ -926,7 +887,8 @@ public static Task CommandScalarExecutedAsync( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -967,11 +929,8 @@ public static Task CommandNonQueryExecutedAsync( LogCommandExecuted(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandExecuted( diagnostics, @@ -986,7 +945,8 @@ public static Task CommandNonQueryExecutedAsync( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1010,7 +970,8 @@ private static CommandExecutedEventData BroadcastCommandExecuted( DateTimeOffset startTime, TimeSpan duration, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new CommandExecutedEventData( definition, @@ -1027,12 +988,7 @@ private static CommandExecutedEventData BroadcastCommandExecuted( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1043,12 +999,10 @@ private static void LogCommandExecuted( TimeSpan duration, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, string.Format(CultureInfo.InvariantCulture, "{0:N0}", duration.TotalMilliseconds), command.Parameters.FormatParameters(ShouldLogParameterValues(diagnostics, command)), command.CommandType, @@ -1100,11 +1054,8 @@ public static void CommandError( LogCommandError(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandError( diagnostics, @@ -1119,7 +1070,8 @@ public static void CommandError( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.CommandFailed(command, eventData); } @@ -1131,12 +1083,10 @@ private static void LogCommandError( TimeSpan duration, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, string.Format(CultureInfo.InvariantCulture, "{0:N0}", duration.TotalMilliseconds), command.Parameters.FormatParameters(ShouldLogParameterValues(diagnostics, command)), command.CommandType, @@ -1178,11 +1128,8 @@ public static Task CommandErrorAsync( LogCommandError(diagnostics, command, duration, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCommandError( diagnostics, @@ -1197,7 +1144,8 @@ public static Task CommandErrorAsync( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1221,7 +1169,8 @@ private static CommandErrorEventData BroadcastCommandError( DateTimeOffset startTime, TimeSpan duration, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new CommandErrorEventData( definition, @@ -1238,12 +1187,7 @@ private static CommandErrorEventData BroadcastCommandError( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1277,11 +1221,8 @@ public static InterceptionResult ConnectionOpening( LogConnectionOpening(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionOpening( diagnostics, @@ -1289,7 +1230,8 @@ public static InterceptionResult ConnectionOpening( startTime, definition, false, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1318,11 +1260,8 @@ public static Task ConnectionOpeningAsync( LogConnectionOpening(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionOpening( diagnostics, @@ -1330,7 +1269,8 @@ public static Task ConnectionOpeningAsync( startTime, definition, true, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1346,12 +1286,10 @@ private static void LogConnectionOpening( IRelationalConnection connection, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, connection.DbConnection.Database, connection.DbConnection.DataSource); } } @@ -1362,7 +1300,8 @@ private static ConnectionEventData BroadcastConnectionOpening( DateTimeOffset startTime, EventDefinition definition, bool async, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new ConnectionEventData( definition, @@ -1373,10 +1312,7 @@ private static ConnectionEventData BroadcastConnectionOpening( async, startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1407,11 +1343,8 @@ public static void ConnectionOpened( LogConnectionOpened(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionOpened( diagnostics, @@ -1420,7 +1353,8 @@ public static void ConnectionOpened( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.ConnectionOpened(connection.DbConnection, eventData); } @@ -1446,11 +1380,8 @@ public static Task ConnectionOpenedAsync( LogConnectionOpened(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionOpened( diagnostics, @@ -1459,7 +1390,8 @@ public static Task ConnectionOpenedAsync( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1477,7 +1409,8 @@ private static ConnectionEndEventData BroadcastConnectionOpened( DateTimeOffset startTime, TimeSpan duration, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new ConnectionEndEventData( definition, @@ -1489,10 +1422,7 @@ private static ConnectionEndEventData BroadcastConnectionOpened( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1502,12 +1432,10 @@ private static void LogConnectionOpened( IRelationalConnection connection, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, connection.DbConnection.Database, connection.DbConnection.DataSource); } } @@ -1537,11 +1465,8 @@ public static InterceptionResult ConnectionClosing( LogConnectionClosing(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionClosing( diagnostics, @@ -1549,7 +1474,8 @@ public static InterceptionResult ConnectionClosing( startTime, false, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1576,11 +1502,8 @@ public static Task ConnectionClosingAsync( LogConnectionClosing(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionClosing( diagnostics, @@ -1588,7 +1511,8 @@ public static Task ConnectionClosingAsync( startTime, true, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1605,7 +1529,8 @@ private static ConnectionEventData BroadcastConnectionClosing( DateTimeOffset startTime, bool async, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new ConnectionEventData( definition, @@ -1616,10 +1541,7 @@ private static ConnectionEventData BroadcastConnectionClosing( async, startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1629,12 +1551,10 @@ private static void LogConnectionClosing( IRelationalConnection connection, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, connection.DbConnection.Database, connection.DbConnection.DataSource); } } @@ -1665,11 +1585,8 @@ public static void ConnectionClosed( LogConnectionClosed(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCollectionClosed( diagnostics, @@ -1678,7 +1595,8 @@ public static void ConnectionClosed( duration, false, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.ConnectionClosed(connection.DbConnection, eventData); } @@ -1702,11 +1620,8 @@ public static Task ConnectionClosedAsync( LogConnectionClosed(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastCollectionClosed( diagnostics, @@ -1715,7 +1630,8 @@ public static Task ConnectionClosedAsync( duration, true, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1733,7 +1649,8 @@ private static ConnectionEndEventData BroadcastCollectionClosed( TimeSpan duration, bool async, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new ConnectionEndEventData( definition, @@ -1745,10 +1662,7 @@ private static ConnectionEndEventData BroadcastCollectionClosed( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1758,12 +1672,10 @@ private static void LogConnectionClosed( IRelationalConnection connection, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, connection.DbConnection.Database, connection.DbConnection.DataSource); } } @@ -1800,11 +1712,8 @@ public static void ConnectionError( LogConnectionError(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionError( diagnostics, @@ -1814,7 +1723,8 @@ public static void ConnectionError( duration, false, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.ConnectionFailed(connection.DbConnection, eventData); } @@ -1846,11 +1756,8 @@ public static Task ConnectionErrorAsync( LogConnectionError(diagnostics, connection, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastConnectionError( diagnostics, @@ -1860,7 +1767,8 @@ public static Task ConnectionErrorAsync( duration, true, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1879,7 +1787,8 @@ private static ConnectionErrorEventData BroadcastConnectionError( TimeSpan duration, bool async, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new ConnectionErrorEventData( definition, @@ -1892,10 +1801,7 @@ private static ConnectionErrorEventData BroadcastConnectionError( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -1905,12 +1811,10 @@ private static void LogConnectionError( IRelationalConnection connection, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, connection.DbConnection.Database, connection.DbConnection.DataSource); } } @@ -1944,11 +1848,8 @@ public static InterceptionResult TransactionStarting( LogTransactionStarting(diagnostics, isolationLevel, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionStarting( diagnostics, @@ -1958,7 +1859,8 @@ public static InterceptionResult TransactionStarting( false, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -1991,11 +1893,8 @@ public static Task> TransactionStartingAsync( LogTransactionStarting(diagnostics, isolationLevel, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionStarting( diagnostics, @@ -2005,7 +1904,8 @@ public static Task> TransactionStartingAsync( true, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2024,7 +1924,8 @@ private static TransactionStartingEventData BroadcastTransactionStarting( bool async, DateTimeOffset startTime, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionStartingEventData( definition, @@ -2036,10 +1937,7 @@ private static TransactionStartingEventData BroadcastTransactionStarting( async, startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -2049,13 +1947,9 @@ private static void LogTransactionStarting( IsolationLevel isolationLevel, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - isolationLevel.ToString("G")); + definition.Log(diagnostics, isolationLevel.ToString("G")); } } @@ -2089,11 +1983,8 @@ public static DbTransaction TransactionStarted( LogTransactionStarted(diagnostics, transaction, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionStarted( diagnostics, @@ -2104,7 +1995,8 @@ public static DbTransaction TransactionStarted( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2139,11 +2031,8 @@ public static Task TransactionStartedAsync( LogTransactionStarted(diagnostics, transaction, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionStarted( diagnostics, @@ -2154,7 +2043,8 @@ public static Task TransactionStartedAsync( startTime, duration, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2174,7 +2064,8 @@ private static TransactionEndEventData BroadcastTransactionStarted( DateTimeOffset startTime, TimeSpan duration, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionEndEventData( definition, @@ -2187,10 +2078,7 @@ private static TransactionEndEventData BroadcastTransactionStarted( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -2200,13 +2088,9 @@ private static void LogTransactionStarted( DbTransaction transaction, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - transaction.IsolationLevel.ToString("G")); + definition.Log(diagnostics, transaction.IsolationLevel.ToString("G")); } } @@ -2237,11 +2121,8 @@ public static DbTransaction TransactionUsed( LogTransactionUsed(diagnostics, transaction, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcasstTransactionUsed( diagnostics, @@ -2251,7 +2132,8 @@ public static DbTransaction TransactionUsed( false, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2284,11 +2166,8 @@ public static Task TransactionUsedAsync( LogTransactionUsed(diagnostics, transaction, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcasstTransactionUsed( diagnostics, @@ -2298,7 +2177,8 @@ public static Task TransactionUsedAsync( true, startTime, definition, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2317,7 +2197,8 @@ private static TransactionEventData BroadcasstTransactionUsed( bool async, DateTimeOffset startTime, EventDefinition definition, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionEventData( definition, @@ -2334,6 +2215,11 @@ private static TransactionEventData BroadcasstTransactionUsed( diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); } + if (simpleLogEnabled) + { + diagnostics.SimpleLogger.Log(eventData); + } + return eventData; } @@ -2342,13 +2228,9 @@ private static void LogTransactionUsed( DbTransaction transaction, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - transaction.IsolationLevel.ToString("G")); + definition.Log(diagnostics, transaction.IsolationLevel.ToString("G")); } } @@ -2380,11 +2262,8 @@ public static InterceptionResult TransactionCommitting( LogTransactionCommitting(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionCommitting( diagnostics, @@ -2394,7 +2273,8 @@ public static InterceptionResult TransactionCommitting( startTime, definition, false, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2427,11 +2307,8 @@ public static Task TransactionCommittingAsync( LogTransactionCommitting(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionCommitting( diagnostics, @@ -2441,7 +2318,8 @@ public static Task TransactionCommittingAsync( startTime, definition, true, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2460,7 +2338,8 @@ private static TransactionEventData BroadcastTransactionCommitting( DateTimeOffset startTime, EventDefinition definition, bool async, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionEventData( definition, @@ -2472,10 +2351,7 @@ private static TransactionEventData BroadcastTransactionCommitting( async, startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -2484,10 +2360,9 @@ private static void LogTransactionCommitting( IDiagnosticsLogger diagnostics, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } } @@ -2512,11 +2387,8 @@ public static void TransactionCommitted( LogTransactionCommitted(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionCommitted( diagnostics, @@ -2527,7 +2399,8 @@ public static void TransactionCommitted( duration, definition, false, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.TransactionCommitted(transaction, eventData); } @@ -2557,11 +2430,8 @@ public static Task TransactionCommittedAsync( LogTransactionCommitted(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionCommitted( diagnostics, @@ -2572,7 +2442,8 @@ public static Task TransactionCommittedAsync( duration, definition, true, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2592,7 +2463,8 @@ private static TransactionEndEventData BroadcastTransactionCommitted( TimeSpan duration, EventDefinition definition, bool async, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionEndEventData( definition, @@ -2605,10 +2477,7 @@ private static TransactionEndEventData BroadcastTransactionCommitted( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -2617,10 +2486,9 @@ private static void LogTransactionCommitted( IDiagnosticsLogger diagnostics, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } } @@ -2645,11 +2513,8 @@ public static void TransactionRolledBack( LogTransactionRolledBack(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionRolledBack( diagnostics, @@ -2660,7 +2525,8 @@ public static void TransactionRolledBack( duration, definition, false, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.TransactionRolledBack(transaction, eventData); } @@ -2690,11 +2556,8 @@ public static Task TransactionRolledBackAsync( LogTransactionRolledBack(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionRolledBack( diagnostics, @@ -2705,7 +2568,8 @@ public static Task TransactionRolledBackAsync( duration, definition, true, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2725,7 +2589,8 @@ private static TransactionEndEventData BroadcastTransactionRolledBack( TimeSpan duration, EventDefinition definition, bool async, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionEndEventData( definition, @@ -2738,10 +2603,7 @@ private static TransactionEndEventData BroadcastTransactionRolledBack( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -2750,10 +2612,9 @@ private static void LogTransactionRolledBack( IDiagnosticsLogger diagnostics, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } } @@ -2777,11 +2638,8 @@ public static InterceptionResult TransactionRollingBack( LogTransactionRollingBack(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionRollingBack( diagnostics, @@ -2791,7 +2649,8 @@ public static InterceptionResult TransactionRollingBack( startTime, definition, false, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2824,11 +2683,8 @@ public static Task TransactionRollingBackAsync( LogTransactionRollingBack(diagnostics, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionRollingBack( diagnostics, @@ -2838,7 +2694,8 @@ public static Task TransactionRollingBackAsync( startTime, definition, true, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -2857,7 +2714,8 @@ private static TransactionEventData BroadcastTransactionRollingBack( DateTimeOffset startTime, EventDefinition definition, bool async, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionEventData( definition, @@ -2869,10 +2727,7 @@ private static TransactionEventData BroadcastTransactionRollingBack( async, startTime); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -2881,10 +2736,9 @@ private static void LogTransactionRollingBack( IDiagnosticsLogger diagnostics, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } } @@ -2905,25 +2759,24 @@ public static void TransactionDisposed( { var definition = RelationalResources.LogDisposingTransaction(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TransactionEventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage(), - transaction, - connection.Context, - transactionId, - connection.ConnectionId, - false, - startTime)); + var eventData = new TransactionEventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage(), + transaction, + connection.Context, + transactionId, + connection.ConnectionId, + false, + startTime); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2952,11 +2805,8 @@ public static void TransactionError( LogTransactionError(diagnostics, exception, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionError( diagnostics, @@ -2969,7 +2819,8 @@ public static void TransactionError( duration, definition, false, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); interceptor?.TransactionFailed(transaction, eventData); } @@ -3003,11 +2854,8 @@ public static Task TransactionErrorAsync( LogTransactionError(diagnostics, exception, definition); - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = BroadcastTransactionError( diagnostics, @@ -3020,7 +2868,8 @@ public static Task TransactionErrorAsync( duration, definition, true, - diagnosticSourceEnabled); + diagnosticSourceEnabled, + simpleLogEnabled); if (interceptor != null) { @@ -3042,7 +2891,8 @@ private static TransactionErrorEventData BroadcastTransactionError( TimeSpan duration, EventDefinition definition, bool async, - bool diagnosticSourceEnabled) + bool diagnosticSourceEnabled, + bool simpleLogEnabled) { var eventData = new TransactionErrorEventData( definition, @@ -3057,10 +2907,7 @@ private static TransactionErrorEventData BroadcastTransactionError( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); return eventData; } @@ -3070,10 +2917,9 @@ private static void LogTransactionError( Exception exception, EventDefinition definition) { - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior, exception); + definition.Log(diagnostics); } } @@ -3090,24 +2936,23 @@ public static void AmbientTransactionWarning( { var definition = RelationalResources.LogAmbientTransaction(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ConnectionEventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage(), - connection.DbConnection, - connection.Context, - connection.ConnectionId, - false, - startTime)); + var eventData = new ConnectionEventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage(), + connection.DbConnection, + connection.Context, + connection.ConnectionId, + false, + startTime); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3124,25 +2969,21 @@ public static void AmbientTransactionEnlisted( { var definition = RelationalResources.LogAmbientTransactionEnlisted(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - transaction.IsolationLevel.ToString("G")); + definition.Log(diagnostics, transaction.IsolationLevel.ToString("G")); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TransactionEnlistedEventData( - definition, - AmbientTransactionEnlisted, - transaction, - connection.DbConnection, - connection.ConnectionId)); + var eventData = new TransactionEnlistedEventData( + definition, + AmbientTransactionEnlisted, + transaction, + connection.DbConnection, + connection.ConnectionId); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3166,25 +3007,21 @@ public static void ExplicitTransactionEnlisted( { var definition = RelationalResources.LogExplicitTransactionEnlisted(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - transaction.IsolationLevel.ToString("G")); + definition.Log(diagnostics, transaction.IsolationLevel.ToString("G")); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TransactionEnlistedEventData( - definition, - ExplicitTransactionEnlisted, - transaction, - connection.DbConnection, - connection.ConnectionId)); + var eventData = new TransactionEnlistedEventData( + definition, + ExplicitTransactionEnlisted, + transaction, + connection.DbConnection, + connection.ConnectionId); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3221,17 +3058,13 @@ public static InterceptionResult DataReaderDisposing( { var definition = RelationalResources.LogDisposingDataReader(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - var diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); - var interceptor = diagnostics.Interceptors?.Aggregate(); - - if (interceptor != null - || diagnosticSourceEnabled) + if (diagnostics.NeedsEventData( + definition, out var interceptor, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { var eventData = new DataReaderDisposingEventData( definition, @@ -3246,12 +3079,7 @@ public static InterceptionResult DataReaderDisposing( startTime, duration); - if (diagnosticSourceEnabled) - { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - eventData); - } + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); if (interceptor != null) { @@ -3275,27 +3103,23 @@ public static void MigrateUsingConnection( { var definition = RelationalResources.LogMigrating(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { var dbConnection = connection.DbConnection; - definition.Log( - diagnostics, - warningBehavior, - dbConnection.Database, dbConnection.DataSource); + definition.Log(diagnostics, dbConnection.Database, dbConnection.DataSource); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigratorConnectionEventData( - definition, - MigrateUsingConnection, - migrator, - connection.DbConnection, - connection.ConnectionId)); + var eventData = new MigratorConnectionEventData( + definition, + MigrateUsingConnection, + migrator, + connection.DbConnection, + connection.ConnectionId); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3321,24 +3145,20 @@ public static void MigrationReverting( { var definition = RelationalResources.LogRevertingMigration(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - migration.GetId()); + definition.Log(diagnostics, migration.GetId()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigrationEventData( - definition, - MigrationReverting, - migrator, - migration)); + var eventData = new MigrationEventData( + definition, + MigrationReverting, + migrator, + migration); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3362,24 +3182,20 @@ public static void MigrationApplying( { var definition = RelationalResources.LogApplyingMigration(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - migration.GetId()); + definition.Log(diagnostics, migration.GetId()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigrationEventData( - definition, - MigrationApplying, - migrator, - migration)); + var eventData = new MigrationEventData( + definition, + MigrationApplying, + migrator, + migration); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3409,27 +3225,23 @@ public static void MigrationGeneratingDownScript( { var definition = RelationalResources.LogGeneratingDown(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - migration.GetId()); + definition.Log(diagnostics, migration.GetId()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigrationScriptingEventData( - definition, - MigrationGeneratingDownScript, - migrator, - migration, - fromMigration, - toMigration, - idempotent)); + var eventData = new MigrationScriptingEventData( + definition, + MigrationGeneratingDownScript, + migrator, + migration, + fromMigration, + toMigration, + idempotent); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3459,27 +3271,23 @@ public static void MigrationGeneratingUpScript( { var definition = RelationalResources.LogGeneratingUp(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - migration.GetId()); + definition.Log(diagnostics, migration.GetId()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigrationScriptingEventData( - definition, - MigrationGeneratingUpScript, - migrator, - migration, - fromMigration, - toMigration, - idempotent)); + var eventData = new MigrationScriptingEventData( + definition, + MigrationGeneratingUpScript, + migrator, + migration, + fromMigration, + toMigration, + idempotent); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3501,20 +3309,19 @@ public static void MigrationsNotApplied( { var definition = RelationalResources.LogNoMigrationsApplied(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigratorEventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage(), - migrator)); + var eventData = new MigratorEventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage(), + migrator); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3531,24 +3338,20 @@ public static void MigrationsNotFound( { var definition = RelationalResources.LogNoMigrationsFound(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - migrationsAssembly.Assembly.GetName().Name); + definition.Log(diagnostics, migrationsAssembly.Assembly.GetName().Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigrationAssemblyEventData( - definition, - MigrationsNotFound, - migrator, - migrationsAssembly)); + var eventData = new MigrationAssemblyEventData( + definition, + MigrationsNotFound, + migrator, + migrationsAssembly); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3570,23 +3373,19 @@ public static void MigrationAttributeMissingWarning( { var definition = RelationalResources.LogMigrationAttributeMissingWarning(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - migrationType.Name); + definition.Log(diagnostics, migrationType.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MigrationTypeEventData( - definition, - MigrationAttributeMissingWarning, - migrationType)); + var eventData = new MigrationTypeEventData( + definition, + MigrationAttributeMissingWarning, + migrationType); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3608,23 +3407,19 @@ public static void QueryPossibleUnintendedUseOfEqualsWarning( { var definition = RelationalResources.LogPossibleUnintendedUseOfEquals(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - methodCallExpression); + definition.Log(diagnostics, methodCallExpression); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ExpressionEventData( - definition, - QueryPossibleUnintendedUseOfEqualsWarning, - methodCallExpression)); + var eventData = new ExpressionEventData( + definition, + QueryPossibleUnintendedUseOfEqualsWarning, + methodCallExpression); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3644,19 +3439,18 @@ public static void QueryPossibleExceptionWithAggregateOperatorWarning( { var definition = RelationalResources.LogQueryPossibleExceptionWithAggregateOperatorWarning(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new EventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage())); + var eventData = new EventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage()); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3671,24 +3465,19 @@ public static void ModelValidationKeyDefaultValueWarning( { var definition = RelationalResources.LogKeyHasDefaultValue(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.Name, - property.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics, property.Name, property.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyEventData( - definition, - ModelValidationKeyDefaultValueWarning, - property)); + var eventData = new PropertyEventData( + definition, + ModelValidationKeyDefaultValueWarning, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3712,24 +3501,19 @@ public static void BoolWithDefaultWarning( { var definition = RelationalResources.LogBoolWithDefaultWarning(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.Name, - property.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics, property.Name, property.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyEventData( - definition, - BoolWithDefaultWarning, - property)); + var eventData = new PropertyEventData( + definition, + BoolWithDefaultWarning, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3753,24 +3537,20 @@ public static void BatchReadyForExecution( { var definition = RelationalResources.LogBatchReadyForExecution(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - commandCount); + definition.Log(diagnostics, commandCount); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new BatchEventData( - definition, - BatchReadyForExecution, - entries, - commandCount)); + var eventData = new BatchEventData( + definition, + BatchReadyForExecution, + entries, + commandCount); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3796,25 +3576,21 @@ public static void BatchSmallerThanMinBatchSize( { var definition = RelationalResources.LogBatchSmallerThanMinBatchSize(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - commandCount, minBatchSize); + definition.Log(diagnostics, commandCount, minBatchSize); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new MinBatchSizeEventData( - definition, - BatchSmallerThanMinBatchSize, - entries, - commandCount, - minBatchSize)); + var eventData = new MinBatchSizeEventData( + definition, + BatchSmallerThanMinBatchSize, + entries, + commandCount, + minBatchSize); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } diff --git a/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs b/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs index c2a4f3c5a2b..3c12bb86816 100644 --- a/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs +++ b/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs @@ -54,7 +54,7 @@ public RelationalCompiledQueryCacheKeyGenerator( /// The query to get the cache key for. /// A value indicating whether the query will be executed asynchronously. /// The cache key. - public override object GenerateCacheKey(Expression query, bool async) + public override object GenerateCacheKey(Expression query, bool async) // Intentionally non-virtual => GenerateCacheKeyCore(query, async); /// diff --git a/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs index b3702853612..da9c1878746 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs @@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions { [DebuggerDisplay("{DebuggerDisplay(),nq}")] - public class ColumnExpression : SqlExpression + public sealed class ColumnExpression : SqlExpression { internal ColumnExpression(IProperty property, TableExpressionBase table, bool nullable) : this( diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index 095a86ec410..5b10705db3a 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions { - public class SelectExpression : TableExpressionBase + public sealed class SelectExpression : TableExpressionBase { private readonly IDictionary> _entityProjectionCache = new Dictionary>(); diff --git a/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs index 4a846a29795..8f70295dd6b 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions { - public class SqlParameterExpression : SqlExpression + public sealed class SqlParameterExpression : SqlExpression { private readonly ParameterExpression _parameterExpression; diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs index 134b84a618d..3be59af7b72 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs @@ -6,7 +6,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions { - public class TableExpression : TableExpressionBase + public sealed class TableExpression : TableExpressionBase { internal TableExpression(string name, string schema, [NotNull] string alias) : base(alias) diff --git a/src/EFCore.SqlServer/Internal/SqlServerLoggerExtensions.cs b/src/EFCore.SqlServer/Internal/SqlServerLoggerExtensions.cs index 4e605602bbc..1343fdc7ddf 100644 --- a/src/EFCore.SqlServer/Internal/SqlServerLoggerExtensions.cs +++ b/src/EFCore.SqlServer/Internal/SqlServerLoggerExtensions.cs @@ -28,23 +28,19 @@ public static void DecimalTypeDefaultWarning( { var definition = SqlServerResources.LogDefaultDecimalTypeColumn(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.Name, property.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics, property.Name, property.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyEventData( - definition, - DecimalTypeDefaultWarning, - property)); + var eventData = new PropertyEventData( + definition, + DecimalTypeDefaultWarning, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -69,23 +65,19 @@ public static void ByteIdentityColumnWarning( { var definition = SqlServerResources.LogByteIdentityColumn(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.Name, property.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics, property.Name, property.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyEventData( - definition, - ByteIdentityColumnWarning, - property)); + var eventData = new PropertyEventData( + definition, + ByteIdentityColumnWarning, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -120,12 +112,10 @@ public static void ColumnFound( { var definition = SqlServerResources.LogFoundColumn(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, l => l.LogDebug( definition.EventId, null, @@ -161,13 +151,9 @@ public static void ForeignKeyFound( { var definition = SqlServerResources.LogFoundForeignKey(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - foreignKeyName, tableName, principalTableName, onDeleteAction); + definition.Log(diagnostics, foreignKeyName, tableName, principalTableName, onDeleteAction); } // No DiagnosticsSource events because these are purely design-time messages @@ -185,13 +171,9 @@ public static void DefaultSchemaFound( { var definition = SqlServerResources.LogFoundDefaultSchema(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - schemaName); + definition.Log(diagnostics, schemaName); } // No DiagnosticsSource events because these are purely design-time messages @@ -210,13 +192,9 @@ public static void TypeAliasFound( { var definition = SqlServerResources.LogFoundTypeAlias(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - typeAliasName, systemTypeName); + definition.Log(diagnostics, typeAliasName, systemTypeName); } // No DiagnosticsSource events because these are purely design-time messages @@ -235,13 +213,9 @@ public static void PrimaryKeyFound( { var definition = SqlServerResources.LogFoundPrimaryKey(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - primaryKeyName, tableName); + definition.Log(diagnostics, primaryKeyName, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -260,13 +234,9 @@ public static void UniqueConstraintFound( { var definition = SqlServerResources.LogFoundUniqueConstraint(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - uniqueConstraintName, tableName); + definition.Log(diagnostics, uniqueConstraintName, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -286,13 +256,9 @@ public static void IndexFound( { var definition = SqlServerResources.LogFoundIndex(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - indexName, tableName, unique); + definition.Log(diagnostics, indexName, tableName, unique); } // No DiagnosticsSource events because these are purely design-time messages @@ -312,13 +278,9 @@ public static void ForeignKeyReferencesMissingPrincipalTableWarning( { var definition = SqlServerResources.LogPrincipalTableNotInSelectionSet(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - foreignKeyName, tableName, principalTableName); + definition.Log(diagnostics, foreignKeyName, tableName, principalTableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -339,13 +301,9 @@ public static void ForeignKeyPrincipalColumnMissingWarning( { var definition = SqlServerResources.LogPrincipalColumnNotFound(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - foreignKeyName, tableName, principalColumnName, principalTableName); + definition.Log(diagnostics, foreignKeyName, tableName, principalColumnName, principalTableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -363,13 +321,9 @@ public static void MissingSchemaWarning( { var definition = SqlServerResources.LogMissingSchema(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - schemaName); + definition.Log(diagnostics, schemaName); } // No DiagnosticsSource events because these are purely design-time messages @@ -387,13 +341,9 @@ public static void MissingTableWarning( { var definition = SqlServerResources.LogMissingTable(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - tableName); + definition.Log(diagnostics, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -418,12 +368,10 @@ public static void SequenceFound( // No DiagnosticsSource events because these are purely design-time messages var definition = SqlServerResources.LogFoundSequence(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, l => l.LogDebug( definition.EventId, null, @@ -450,13 +398,9 @@ public static void TableFound( { var definition = SqlServerResources.LogFoundTable(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - tableName); + definition.Log(diagnostics, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -475,13 +419,9 @@ public static void ReflexiveConstraintIgnored( { var definition = SqlServerResources.LogReflexiveConstraintIgnored(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - foreignKeyName, tableName); + definition.Log(diagnostics, foreignKeyName, tableName); } // No DiagnosticsSource events because these are purely design-time messages diff --git a/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs b/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs index d466a46c66a..448dc291b9a 100644 --- a/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs +++ b/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs @@ -28,24 +28,20 @@ public static void SchemaConfiguredWarning( { var definition = SqliteResources.LogSchemaConfigured(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - entityType.DisplayName(), schema); + definition.Log(diagnostics, entityType.DisplayName(), schema); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new EntityTypeSchemaEventData( - definition, - SchemaConfiguredWarning, - entityType, - schema)); + var eventData = new EntityTypeSchemaEventData( + definition, + SchemaConfiguredWarning, + entityType, + schema); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -70,23 +66,19 @@ public static void SequenceConfiguredWarning( { var definition = SqliteResources.LogSequenceConfigured(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - sequence.Name); + definition.Log(diagnostics, sequence.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new SequenceEventData( - definition, - SequenceConfiguredWarning, - sequence)); + var eventData = new SequenceEventData( + definition, + SequenceConfiguredWarning, + sequence); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -113,13 +105,9 @@ public static void ColumnFound( { var definition = SqliteResources.LogFoundColumn(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - tableName, columnName, dataTypeName, notNull, defaultValue); + definition.Log(diagnostics, tableName, columnName, dataTypeName, notNull, defaultValue); } // No DiagnosticsSource events because these are purely design-time messages @@ -136,10 +124,9 @@ public static void SchemasNotSupportedWarning( { var definition = SqliteResources.LogUsingSchemaSelectionsWarning(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } // No DiagnosticsSource events because these are purely design-time messages @@ -157,13 +144,9 @@ public static void ForeignKeyReferencesMissingTableWarning( { var definition = SqliteResources.LogForeignKeyScaffoldErrorPrincipalTableNotFound(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - foreignKeyName); + definition.Log(diagnostics, foreignKeyName); } // No DiagnosticsSource events because these are purely design-time messages @@ -181,13 +164,9 @@ public static void TableFound( { var definition = SqliteResources.LogFoundTable(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - tableName); + definition.Log(diagnostics, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -205,13 +184,9 @@ public static void MissingTableWarning( { var definition = SqliteResources.LogMissingTable(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - tableName); + definition.Log(diagnostics, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -232,13 +207,9 @@ public static void ForeignKeyPrincipalColumnMissingWarning( { var definition = SqliteResources.LogPrincipalColumnNotFound(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - foreignKeyName, tableName, principalColumnName, principalTableName); + definition.Log(diagnostics, foreignKeyName, tableName, principalColumnName, principalTableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -258,13 +229,9 @@ public static void IndexFound( { var definition = SqliteResources.LogFoundIndex(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - indexName, tableName, unique); + definition.Log(diagnostics, indexName, tableName, unique); } // No DiagnosticsSource events because these are purely design-time messages @@ -285,13 +252,9 @@ public static void ForeignKeyFound( { var definition = SqliteResources.LogFoundForeignKey(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - tableName, id, principalTableName, deleteAction); + definition.Log(diagnostics, tableName, id, principalTableName, deleteAction); } // No DiagnosticsSource events because these are purely design-time messages @@ -310,13 +273,9 @@ public static void PrimaryKeyFound( { var definition = SqliteResources.LogFoundPrimaryKey(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - primaryKeyName, tableName); + definition.Log(diagnostics, primaryKeyName, tableName); } // No DiagnosticsSource events because these are purely design-time messages @@ -335,13 +294,9 @@ public static void UniqueConstraintFound( { var definition = SqliteResources.LogFoundUniqueConstraint(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - uniqueConstraintName, tableName); + definition.Log(diagnostics, uniqueConstraintName, tableName); } // No DiagnosticsSource events because these are purely design-time messages diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs index 440a9861a10..9b3d6d3479a 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs @@ -1005,7 +1005,7 @@ public virtual void AddRangeToCollectionSnapshot( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public object this[[NotNull] IPropertyBase propertyBase] + public object this[[NotNull] IPropertyBase propertyBase] // Intentionally non-virtual { get { @@ -1447,7 +1447,7 @@ public virtual bool IsStoreGenerated(IProperty property) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool HasDefaultValue(IProperty property) + public bool HasDefaultValue(IProperty property) // Intentionally non-virtual { if (!PropertyHasDefaultValue(property)) { diff --git a/src/EFCore/DbContextOptionsBuilder.cs b/src/EFCore/DbContextOptionsBuilder.cs index 58989b7adfe..e27595a9f9c 100644 --- a/src/EFCore/DbContextOptionsBuilder.cs +++ b/src/EFCore/DbContextOptionsBuilder.cs @@ -106,6 +106,212 @@ public virtual DbContextOptionsBuilder UseModel([NotNull] IModel model) public virtual DbContextOptionsBuilder UseLoggerFactory([CanBeNull] ILoggerFactory loggerFactory) => WithOption(e => e.WithLoggerFactory(loggerFactory)); + /// + /// + /// Logs to the supplied sink. For example, use optionsBuilder.LogTo(Console.WriteLine) to + /// log to the console. + /// + /// + /// This overload allows the minimum level of logging and the log formatting to be controlled. + /// Use the + /// overload to log only specific events. + /// Use the + /// overload to log only events in specific categories. + /// Use the + /// overload to use a custom filter for events. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// The minimum level of logging event to log. Defaults to + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + LogLevel minimumLevel = LogLevel.Debug, + SimpleLoggerFormatOptions? formatOptions = null) + => LogTo(sink, (i, l) => l >= minimumLevel, formatOptions); + + /// + /// + /// Logs the specified events to the supplied sink. For example, use + /// optionsBuilder.LogTo(Console.WriteLine, new[] { CoreEventId.ContextInitialized }) to log the + /// event to the console. + /// + /// + /// Use the overload for default logging of + /// all events. + /// Use the + /// overload to log only events in specific categories. + /// Use the + /// overload to use a custom filter for events. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// The of each event to log. + /// The minimum level of logging event to log. Defaults to + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + [NotNull] IEnumerable events, + LogLevel minimumLevel = LogLevel.Debug, + SimpleLoggerFormatOptions? formatOptions = null) + { + Check.NotNull(events, nameof(events)); + + var eventsArray = events.ToArray(); + if (eventsArray.Length == 0 || eventsArray.Length > 5) + { + return LogTo( + sink, + (eventId, level) => level >= minimumLevel + && eventsArray.Contains(eventId), + formatOptions); + } + + if (eventsArray.Length == 1) + { + var firstEvent = eventsArray[0]; + return LogTo( + sink, + (eventId, level) => level >= minimumLevel + && eventId == firstEvent, + formatOptions); + } + + var eventsHash = eventsArray.ToHashSet(); + return LogTo( + sink, + (eventId, level) => level >= minimumLevel + && eventsHash.Contains(eventId), + formatOptions); + } + + /// + /// + /// Logs all events in the specified categories to the supplied sink. For example, use + /// optionsBuilder.LogTo(Console.WriteLine, new[] { DbLoggerCategory.Infrastructure.Name }) to log all + /// events in the category. + /// + /// + /// Use the overload for default logging of + /// all events. + /// Use the + /// overload to log only specific events. + /// Use the + /// overload to use a custom filter for events. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// The of each event to log. + /// The minimum level of logging event to log. Defaults to + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + [NotNull] IEnumerable categories, + LogLevel minimumLevel = LogLevel.Debug, + SimpleLoggerFormatOptions? formatOptions = null) + { + Check.NotNull(categories, nameof(categories)); + + var categoriesArray = categories.ToArray(); + if (categoriesArray.Length != 1) + { + // One category is common, but even when there are more the number should be low because + // the number of available categories is low. So no HashSet here. + return LogTo( + sink, + (eventId, level) => + { + if (level >= minimumLevel) + { + for (var i = 0; i < categoriesArray.Length; i++) + { + if (eventId.Name.StartsWith(categoriesArray[i], StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + } + + return false; + }, + formatOptions); + } + + var singleCategory = categoriesArray[0]; + return LogTo( + sink, + (eventId, level) => level >= minimumLevel + && eventId.Name.StartsWith(singleCategory, StringComparison.OrdinalIgnoreCase), + formatOptions); + } + + /// + /// + /// Logs events filtered by a supplied custom filter delegate. The filter should return true to + /// log a message, or false to filter it out of the log. + /// + /// + /// Use the overload for default logging of + /// all events. + /// Use the + /// Use the + /// overload to log only events in specific categories. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// Delegate that returns true to log the message or false to ignore it. + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + [NotNull] Func filter, + SimpleLoggerFormatOptions? formatOptions = null) + { + Check.NotNull(sink, nameof(sink)); + Check.NotNull(filter, nameof(filter)); + + return LogTo(new SimpleLogger(sink, filter, formatOptions ?? SimpleLoggerFormatOptions.DefaultWithLocalTime)); + } + + /// + /// + /// Logs to the supplied implementation. + /// + /// + /// Use this method when the other overloads do not provide enough control over filtering and formatting of the output. + /// Use the overload for default logging of + /// all events. + /// Use the + /// Use the + /// overload to log only events in specific categories. + /// Use the + /// overload to use a custom filter for events. + /// + /// + /// The to use. + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder LogTo([NotNull] ISimpleLogger simpleLogger) + { + Check.NotNull(simpleLogger, nameof(simpleLogger)); + + return WithOption(e => e.WithSimpleLogger(simpleLogger)); + } + /// /// /// Enables detailed errors when handling of data value exceptions that occur during processing of store query results. Such errors diff --git a/src/EFCore/DbContextOptionsBuilder`.cs b/src/EFCore/DbContextOptionsBuilder`.cs index 9eb598ad238..78893f79f50 100644 --- a/src/EFCore/DbContextOptionsBuilder`.cs +++ b/src/EFCore/DbContextOptionsBuilder`.cs @@ -2,11 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -82,6 +84,140 @@ public DbContextOptionsBuilder([NotNull] DbContextOptions options) public new virtual DbContextOptionsBuilder UseLoggerFactory([CanBeNull] ILoggerFactory loggerFactory) => (DbContextOptionsBuilder)base.UseLoggerFactory(loggerFactory); + /// + /// + /// Logs to the supplied sink. For example, use optionsBuilder.LogTo(Console.WriteLine) to + /// log to the console. + /// + /// + /// This overload allows the minimum level of logging and the log formatting to be controlled. + /// Use the + /// overload to log only specific events. + /// Use the + /// overload to log only events in specific categories. + /// Use the + /// overload to use a custom filter for events. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// The minimum level of logging event to log. Defaults to + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + LogLevel minimumLevel = LogLevel.Debug, + SimpleLoggerFormatOptions? formatOptions = null) + => (DbContextOptionsBuilder)base.LogTo(sink, minimumLevel, formatOptions); + + /// + /// + /// Logs the specified events to the supplied sink. For example, use + /// optionsBuilder.LogTo(Console.WriteLine, new[] { CoreEventId.ContextInitialized }) to log the + /// event to the console. + /// + /// + /// Use the overload for default logging of + /// all events. + /// Use the + /// overload to log only events in specific categories. + /// Use the + /// overload to use a custom filter for events. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// The of each event to log. + /// The minimum level of logging event to log. Defaults to + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + [NotNull] IEnumerable events, + LogLevel minimumLevel = LogLevel.Debug, + SimpleLoggerFormatOptions? formatOptions = null) + => (DbContextOptionsBuilder)base.LogTo(sink, events, minimumLevel, formatOptions); + + /// + /// + /// Logs all events in the specified categories to the supplied sink. For example, use + /// optionsBuilder.LogTo(Console.WriteLine, new[] { DbLoggerCategory.Infrastructure.Name }) to log all + /// events in the category. + /// + /// + /// Use the overload for default logging of + /// all events. + /// Use the + /// overload to log only specific events. + /// Use the + /// overload to use a custom filter for events. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// The of each event to log. + /// The minimum level of logging event to log. Defaults to + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + [NotNull] IEnumerable categories, + LogLevel minimumLevel = LogLevel.Debug, + SimpleLoggerFormatOptions? formatOptions = null) + => (DbContextOptionsBuilder)base.LogTo(sink, categories, minimumLevel, formatOptions); + + /// + /// + /// Logs events filtered by a supplied custom filter delegate. The filter should return true to + /// log a message, or false to filter it out of the log. + /// + /// + /// Use the overload for default logging of + /// all events. + /// Use the + /// Use the + /// overload to log only events in specific categories. + /// Use the overload to log to a fully custom logger. + /// + /// + /// The sink to which log messages will be written. + /// Delegate that returns true to log the message or false to ignore it. + /// + /// Formatting options for log messages. Passing null (the default) means use + /// + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder LogTo( + [NotNull] Action sink, + [NotNull] Func filter, + SimpleLoggerFormatOptions? formatOptions = null) + => (DbContextOptionsBuilder)base.LogTo(sink, filter, formatOptions); + + /// + /// + /// Logs to the supplied implementation. + /// + /// + /// Use this method when the other overloads do not provide enough control over filtering and formatting of the output. + /// Use the overload for default logging of + /// all events. + /// Use the + /// Use the + /// overload to log only events in specific categories. + /// Use the + /// overload to use a custom filter for events. + /// + /// + /// The to use. + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder LogTo([NotNull] ISimpleLogger simpleLogger) + => (DbContextOptionsBuilder)base.LogTo(simpleLogger); + /// /// /// Enables detailed errors when handling data value exceptions that occur during processing of store query results. Such errors diff --git a/src/EFCore/DbFunctions.cs b/src/EFCore/DbFunctions.cs index e42d3c1fbf3..f360d6a5878 100644 --- a/src/EFCore/DbFunctions.cs +++ b/src/EFCore/DbFunctions.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore /// Provides CLR methods that get translated to database functions when used in LINQ to Entities queries. /// The methods on this class are accessed via . /// - public class DbFunctions + public sealed class DbFunctions { internal DbFunctions() { diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 2a678c82669..a908ba3d7b2 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -47,25 +47,23 @@ public static void SaveChangesFailed( { var definition = CoreResources.LogExceptionDuringSaveChanges(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, context.GetType(), Environment.NewLine, exception, exception); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextErrorEventData( - definition, - SaveChangesFailed, - context, - exception)); + var eventData = new DbContextErrorEventData( + definition, + SaveChangesFailed, + context, + exception); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -89,24 +87,20 @@ public static void OptimisticConcurrencyException( { var definition = CoreResources.LogOptimisticConcurrencyException(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - exception); + definition.Log(diagnostics, exception); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextErrorEventData( - definition, - OptimisticConcurrencyException, - context, - exception)); + var eventData = new DbContextErrorEventData( + definition, + OptimisticConcurrencyException, + context, + exception); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -130,24 +124,20 @@ public static void DuplicateDependentEntityTypeInstanceWarning( { var definition = CoreResources.LogDuplicateDependentEntityTypeInstance(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - dependent1.DisplayName(), dependent2.DisplayName()); + definition.Log(diagnostics,dependent1.DisplayName(), dependent2.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new SharedDependentEntityEventData( - definition, - DuplicateDependentEntityTypeInstanceWarning, - dependent1, - dependent2)); + var eventData = new SharedDependentEntityEventData( + definition, + DuplicateDependentEntityTypeInstanceWarning, + dependent1, + dependent2); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -171,25 +161,23 @@ public static void QueryIterationFailed( { var definition = CoreResources.LogExceptionDuringQueryIteration(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, contextType, Environment.NewLine, exception, exception); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextTypeErrorEventData( - definition, - QueryIterationFailed, - contextType, - exception)); + var eventData = new DbContextTypeErrorEventData( + definition, + QueryIterationFailed, + contextType, + exception); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -404,24 +392,20 @@ public static void QueryExecutionPlanned( { var definition = CoreResources.LogQueryExecutionPlanned(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - expressionPrinter.Print(queryExecutorExpression)); + definition.Log(diagnostics, expressionPrinter.Print(queryExecutorExpression)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new QueryExpressionEventData( - definition, - QueryExecutionPlanned, - queryExecutorExpression, - expressionPrinter)); + var eventData = new QueryExpressionEventData( + definition, + QueryExecutionPlanned, + queryExecutorExpression, + expressionPrinter); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -443,19 +427,18 @@ public static void SensitiveDataLoggingEnabledWarning( { var definition = CoreResources.LogSensitiveDataLoggingEnabled(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new EventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage())); + var eventData = new EventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage()); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -508,23 +491,21 @@ public static void PossibleUnintendedCollectionNavigationNullComparisonWarning( { var definition = CoreResources.LogPossibleUnintendedCollectionNavigationNullComparison(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, $"{navigation.DeclaringEntityType.Name}.{navigation.GetTargetType().Name}"); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new NavigationEventData( - definition, - PossibleUnintendedCollectionNavigationNullComparisonWarning, - navigation)); + var eventData = new NavigationEventData( + definition, + PossibleUnintendedCollectionNavigationNullComparisonWarning, + navigation); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -548,24 +529,20 @@ public static void PossibleUnintendedReferenceComparisonWarning( { var definition = CoreResources.LogPossibleUnintendedReferenceComparison(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - left, right); + definition.Log(diagnostics,left, right); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new BinaryExpressionEventData( - definition, - PossibleUnintendedReferenceComparisonWarning, - left, - right)); + var eventData = new BinaryExpressionEventData( + definition, + PossibleUnintendedReferenceComparisonWarning, + left, + right); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -587,20 +564,19 @@ public static void ServiceProviderCreated( { var definition = CoreResources.LogServiceProviderCreated(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ServiceProviderEventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage(), - serviceProvider)); + var eventData = new ServiceProviderEventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage(), + serviceProvider); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -615,20 +591,19 @@ public static void ManyServiceProvidersCreatedWarning( { var definition = CoreResources.LogManyServiceProvidersCreated(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, warningBehavior); + definition.Log(diagnostics); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ServiceProvidersEventData( - definition, - (d, p) => ((EventDefinition)d).GenerateMessage(), - serviceProviders)); + var eventData = new ServiceProvidersEventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage(), + serviceProviders); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -645,24 +620,20 @@ public static void ServiceProviderDebugInfo( { var definition = CoreResources.LogServiceProviderDebugInfo(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - GenerateDebugInfoString(newDebugInfo, cachedDebugInfos)); + definition.Log(diagnostics, GenerateDebugInfoString(newDebugInfo, cachedDebugInfos)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ServiceProviderDebugInfoEventData( - definition, - (d, p) => ServiceProviderDebugInfo(d, p), - newDebugInfo, - cachedDebugInfos)); + var eventData = new ServiceProviderDebugInfoEventData( + definition, + (d, p) => ServiceProviderDebugInfo(d, p), + newDebugInfo, + cachedDebugInfos); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -730,27 +701,25 @@ public static void ContextInitialized( { var definition = CoreResources.LogContextInitialized(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, ProductInfo.GetVersion(), context.GetType().ShortDisplayName(), context.Database.ProviderName, contextOptions.BuildOptionsFragment()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ContextInitializedEventData( - definition, - ContextInitialized, - context, - contextOptions)); + var eventData = new ContextInitializedEventData( + definition, + ContextInitialized, + context, + contextOptions); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -780,27 +749,25 @@ public static void ExecutionStrategyRetrying( { var definition = CoreResources.LogExecutionStrategyRetrying(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { var lastException = exceptionsEncountered[exceptionsEncountered.Count - 1]; definition.Log( diagnostics, - warningBehavior, (int)delay.TotalMilliseconds, Environment.NewLine, lastException, lastException); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ExecutionStrategyEventData( - definition, - ExecutionStrategyRetrying, - exceptionsEncountered, - delay, - async)); + var eventData = new ExecutionStrategyEventData( + definition, + ExecutionStrategyRetrying, + exceptionsEncountered, + delay, + async); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -827,25 +794,21 @@ public static void LazyLoadOnDisposedContextWarning( { var definition = CoreResources.LogLazyLoadOnDisposedContext(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigationName, entityType.GetType().ShortDisplayName()); + definition.Log(diagnostics,navigationName, entityType.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new LazyLoadingEventData( - definition, - LazyLoadOnDisposedContextWarning, - context, - entityType, - navigationName)); + var eventData = new LazyLoadingEventData( + definition, + LazyLoadOnDisposedContextWarning, + context, + entityType, + navigationName); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -871,25 +834,21 @@ public static void NavigationLazyLoading( { var definition = CoreResources.LogNavigationLazyLoading(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigationName, entityType.GetType().ShortDisplayName()); + definition.Log(diagnostics,navigationName, entityType.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new LazyLoadingEventData( - definition, - NavigationLazyLoading, - context, - entityType, - navigationName)); + var eventData = new LazyLoadingEventData( + definition, + NavigationLazyLoading, + context, + entityType, + navigationName); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -915,25 +874,21 @@ public static void DetachedLazyLoadingWarning( { var definition = CoreResources.LogDetachedLazyLoading(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigationName, entityType.GetType().ShortDisplayName()); + definition.Log(diagnostics,navigationName, entityType.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new LazyLoadingEventData( - definition, - DetachedLazyLoadingWarning, - context, - entityType, - navigationName)); + var eventData = new LazyLoadingEventData( + definition, + DetachedLazyLoadingWarning, + context, + entityType, + navigationName); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -955,23 +910,19 @@ public static void ShadowPropertyCreated( { var definition = CoreResources.LogShadowPropertyCreated(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.Name, property.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics,property.Name, property.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyEventData( - definition, - ShadowPropertyCreated, - property)); + var eventData = new PropertyEventData( + definition, + ShadowPropertyCreated, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -993,23 +944,19 @@ public static void CollectionWithoutComparer( { var definition = CoreResources.LogCollectionWithoutComparer(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.Name, property.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics,property.Name, property.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyEventData( - definition, - CollectionWithoutComparer, - property)); + var eventData = new PropertyEventData( + definition, + CollectionWithoutComparer, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1033,24 +980,24 @@ public static void RedundantIndexRemoved( { var definition = CoreResources.LogRedundantIndexRemoved(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, - redundantIndex.Format(), redundantIndex.First().DeclaringType.DisplayName(), otherIndex.Format()); + redundantIndex.Format(), + redundantIndex.First().DeclaringType.DisplayName(), + otherIndex.Format()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoPropertyBaseCollectionsEventData( - definition, - RedundantIndexRemoved, - redundantIndex, - otherIndex)); + var eventData = new TwoPropertyBaseCollectionsEventData( + definition, + RedundantIndexRemoved, + redundantIndex, + otherIndex); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1075,23 +1022,22 @@ public static void RedundantForeignKeyWarning( { var definition = CoreResources.LogRedundantForeignKey(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, - redundantForeignKey.Properties.Format(), redundantForeignKey.DeclaringEntityType.DisplayName()); + redundantForeignKey.Properties.Format(), + redundantForeignKey.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ForeignKeyEventData( - definition, - RedundantForeignKeyWarning, - redundantForeignKey)); + var eventData = new ForeignKeyEventData( + definition, + RedundantForeignKeyWarning, + redundantForeignKey); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1117,25 +1063,23 @@ public static void IncompatibleMatchingForeignKeyProperties( { var definition = CoreResources.LogIncompatibleMatchingForeignKeyProperties(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, foreignKeyProperties.Format(includeTypes: true), principalKeyProperties.Format(includeTypes: true)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoPropertyBaseCollectionsEventData( - definition, - IncompatibleMatchingForeignKeyProperties, - foreignKeyProperties, - principalKeyProperties)); + var eventData = new TwoPropertyBaseCollectionsEventData( + definition, + IncompatibleMatchingForeignKeyProperties, + foreignKeyProperties, + principalKeyProperties); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1159,23 +1103,19 @@ public static void RequiredAttributeInverted( { var definition = CoreResources.LogRequiredAttributeInverted(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigation.Name, navigation.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics,navigation.Name, navigation.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new NavigationEventData( - definition, - RequiredAttributeInverted, - navigation)); + var eventData = new NavigationEventData( + definition, + RequiredAttributeInverted, + navigation); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1197,23 +1137,19 @@ public static void NonNullableInverted( { var definition = CoreResources.LogNonNullableInverted(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigation.Name, navigation.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics,navigation.Name, navigation.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new NavigationEventData( - definition, - NonNullableInverted, - navigation)); + var eventData = new NavigationEventData( + definition, + NonNullableInverted, + navigation); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1237,27 +1173,25 @@ public static void RequiredAttributeOnBothNavigations( { var definition = CoreResources.LogRequiredAttributeOnBothNavigations(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, firstNavigation.DeclaringEntityType.DisplayName(), firstNavigation.Name, secondNavigation.DeclaringEntityType.DisplayName(), secondNavigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoPropertyBaseCollectionsEventData( - definition, - RequiredAttributeOnBothNavigations, - new[] { firstNavigation }, - new[] { secondNavigation })); + var eventData = new TwoPropertyBaseCollectionsEventData( + definition, + RequiredAttributeOnBothNavigations, + new[] { firstNavigation }, + new[] { secondNavigation }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1287,27 +1221,25 @@ public static void NonNullableReferenceOnBothNavigations( { var definition = CoreResources.LogNonNullableReferenceOnBothNavigations(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, firstNavigation.DeclaringEntityType.DisplayName(), firstNavigation.Name, secondNavigation.DeclaringEntityType.DisplayName(), secondNavigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoPropertyBaseCollectionsEventData( - definition, - NonNullableReferenceOnBothNavigations, - new[] { firstNavigation }, - new[] { secondNavigation })); + var eventData = new TwoPropertyBaseCollectionsEventData( + definition, + NonNullableReferenceOnBothNavigations, + new[] { firstNavigation }, + new[] { secondNavigation }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1335,23 +1267,21 @@ public static void RequiredAttributeOnDependent( { var definition = CoreResources.LogRequiredAttributeOnDependent(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, navigation.Name, navigation.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new NavigationEventData( - definition, - RequiredAttributeOnDependent, - navigation)); + var eventData = new NavigationEventData( + definition, + RequiredAttributeOnDependent, + navigation); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1373,23 +1303,22 @@ public static void NonNullableReferenceOnDependent( { var definition = CoreResources.LogNonNullableReferenceOnDependent(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, - navigation.Name, navigation.DeclaringEntityType.DisplayName()); + navigation.Name, + navigation.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new NavigationEventData( - definition, - NonNullableReferenceOnDependent, - navigation)); + var eventData = new NavigationEventData( + definition, + NonNullableReferenceOnDependent, + navigation); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1411,23 +1340,19 @@ public static void RequiredAttributeOnCollection( { var definition = CoreResources.LogRequiredAttributeOnCollection(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigation.Name, navigation.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics,navigation.Name,navigation.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new NavigationEventData( - definition, - RequiredAttributeOnCollection, - navigation)); + var eventData = new NavigationEventData( + definition, + RequiredAttributeOnCollection, + navigation); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1449,26 +1374,24 @@ public static void ConflictingShadowForeignKeysWarning( { var definition = CoreResources.LogConflictingShadowForeignKeys(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { var declaringTypeName = foreignKey.DeclaringEntityType.DisplayName(); definition.Log( diagnostics, - warningBehavior, declaringTypeName, foreignKey.PrincipalEntityType.DisplayName(), declaringTypeName); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ForeignKeyEventData( - definition, - ConflictingShadowForeignKeysWarning, - foreignKey)); + var eventData = new ForeignKeyEventData( + definition, + ConflictingShadowForeignKeysWarning, + foreignKey); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1495,26 +1418,24 @@ public static void MultiplePrimaryKeyCandidates( { var definition = CoreResources.LogMultiplePrimaryKeyCandidates(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, firstProperty.Name, secondProperty.Name, firstProperty.DeclaringEntityType.DisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoPropertyBaseCollectionsEventData( - definition, - MultiplePrimaryKeyCandidates, - new[] { firstProperty }, - new[] { secondProperty })); + var eventData = new TwoPropertyBaseCollectionsEventData( + definition, + MultiplePrimaryKeyCandidates, + new[] { firstProperty }, + new[] { secondProperty }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1543,27 +1464,25 @@ public static void MultipleNavigationProperties( { var definition = CoreResources.LogMultipleNavigationProperties(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, firstPropertyCollection.First().Item2.ShortDisplayName(), secondPropertyCollection.First().Item2.ShortDisplayName(), Property.Format(firstPropertyCollection.Select(p => p.Item1?.Name)), Property.Format(secondPropertyCollection.Select(p => p.Item1?.Name))); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoUnmappedPropertyCollectionsEventData( - definition, - MultipleNavigationProperties, - firstPropertyCollection, - secondPropertyCollection)); + var eventData = new TwoUnmappedPropertyCollectionsEventData( + definition, + MultipleNavigationProperties, + firstPropertyCollection, + secondPropertyCollection); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1593,25 +1512,23 @@ public static void MultipleInversePropertiesSameTargetWarning( { var definition = CoreResources.LogMultipleInversePropertiesSameTarget(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, string.Join(", ", conflictingNavigations.Select(n => n.Item2.ShortDisplayName() + "." + n.Item1.Name)), inverseNavigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoUnmappedPropertyCollectionsEventData( - definition, - MultipleInversePropertiesSameTargetWarning, - conflictingNavigations, - new[] { new Tuple(inverseNavigation, targetType) })); + var eventData = new TwoUnmappedPropertyCollectionsEventData( + definition, + MultipleInversePropertiesSameTargetWarning, + conflictingNavigations, + new[] { new Tuple(inverseNavigation, targetType) }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1644,12 +1561,10 @@ public static void NonDefiningInverseNavigationWarning( { var definition = CoreResources.LogNonDefiningInverseNavigation(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, targetType.DisplayName(), inverseNavigation.Name, declaringType.DisplayName(), @@ -1657,19 +1572,19 @@ public static void NonDefiningInverseNavigationWarning( definingNavigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoUnmappedPropertyCollectionsEventData( - definition, - NonDefiningInverseNavigationWarning, - new[] { new Tuple(navigation, declaringType.ClrType) }, - new[] - { - new Tuple(inverseNavigation, targetType.ClrType), - new Tuple(definingNavigation, targetType.ClrType) - })); + var eventData = new TwoUnmappedPropertyCollectionsEventData( + definition, + NonDefiningInverseNavigationWarning, + new[] { new Tuple(navigation, declaringType.ClrType) }, + new[] + { + new Tuple(inverseNavigation, targetType.ClrType), + new Tuple(definingNavigation, targetType.ClrType) + }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1707,12 +1622,10 @@ public static void NonOwnershipInverseNavigationWarning( { var definition = CoreResources.LogNonOwnershipInverseNavigation(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, targetType.DisplayName(), inverseNavigation.Name, declaringType.DisplayName(), @@ -1720,19 +1633,19 @@ public static void NonOwnershipInverseNavigationWarning( ownershipNavigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoUnmappedPropertyCollectionsEventData( - definition, - NonOwnershipInverseNavigationWarning, - new[] { new Tuple(navigation, declaringType.ClrType) }, - new[] - { - new Tuple(inverseNavigation, targetType.ClrType), - new Tuple(ownershipNavigation, targetType.ClrType) - })); + var eventData = new TwoUnmappedPropertyCollectionsEventData( + definition, + NonOwnershipInverseNavigationWarning, + new[] { new Tuple(navigation, declaringType.ClrType) }, + new[] + { + new Tuple(inverseNavigation, targetType.ClrType), + new Tuple(ownershipNavigation, targetType.ClrType) + }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1768,12 +1681,10 @@ public static void ForeignKeyAttributesOnBothPropertiesWarning( { var definition = CoreResources.LogForeignKeyAttributesOnBothProperties(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, firstNavigation.DeclaringEntityType.ClrType.ShortDisplayName(), firstNavigation.GetIdentifyingMemberInfo().Name, secondNavigation.DeclaringEntityType.ClrType.ShortDisplayName(), @@ -1782,25 +1693,25 @@ public static void ForeignKeyAttributesOnBothPropertiesWarning( secondProperty.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoUnmappedPropertyCollectionsEventData( - definition, - ForeignKeyAttributesOnBothPropertiesWarning, - new[] - { - new Tuple( - firstNavigation.GetIdentifyingMemberInfo(), firstNavigation.DeclaringEntityType.ClrType), - new Tuple(firstProperty, firstNavigation.DeclaringEntityType.ClrType) - }, - new[] - { - new Tuple( - secondNavigation.GetIdentifyingMemberInfo(), secondNavigation.DeclaringEntityType.ClrType), - new Tuple(secondProperty, secondNavigation.DeclaringEntityType.ClrType) - })); + var eventData = new TwoUnmappedPropertyCollectionsEventData( + definition, + ForeignKeyAttributesOnBothPropertiesWarning, + new[] + { + new Tuple( + firstNavigation.GetIdentifyingMemberInfo(), firstNavigation.DeclaringEntityType.ClrType), + new Tuple(firstProperty, firstNavigation.DeclaringEntityType.ClrType) + }, + new[] + { + new Tuple( + secondNavigation.GetIdentifyingMemberInfo(), secondNavigation.DeclaringEntityType.ClrType), + new Tuple(secondProperty, secondNavigation.DeclaringEntityType.ClrType) + }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1834,27 +1745,25 @@ public static void ForeignKeyAttributesOnBothNavigationsWarning( { var definition = CoreResources.LogForeignKeyAttributesOnBothNavigations(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, firstNavigation.DeclaringEntityType.DisplayName(), firstNavigation.Name, secondNavigation.DeclaringEntityType.DisplayName(), secondNavigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoPropertyBaseCollectionsEventData( - definition, - ForeignKeyAttributesOnBothNavigationsWarning, - new[] { firstNavigation }, - new[] { secondNavigation })); + var eventData = new TwoPropertyBaseCollectionsEventData( + definition, + ForeignKeyAttributesOnBothNavigationsWarning, + new[] { firstNavigation }, + new[] { secondNavigation }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1884,30 +1793,28 @@ public static void ConflictingForeignKeyAttributesOnNavigationAndPropertyWarning { var definition = CoreResources.LogConflictingForeignKeyAttributesOnNavigationAndProperty(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, navigation.DeclaringEntityType.ClrType.ShortDisplayName(), navigation.GetIdentifyingMemberInfo()?.Name, property.DeclaringType.ShortDisplayName(), property.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new TwoUnmappedPropertyCollectionsEventData( - definition, - ConflictingForeignKeyAttributesOnNavigationAndPropertyWarning, - new[] - { - new Tuple(navigation.GetIdentifyingMemberInfo(), navigation.DeclaringEntityType.ClrType) - }, - new[] { new Tuple(property, property.DeclaringType) })); + var eventData = new TwoUnmappedPropertyCollectionsEventData( + definition, + ConflictingForeignKeyAttributesOnNavigationAndPropertyWarning, + new[] + { + new Tuple(navigation.GetIdentifyingMemberInfo(), navigation.DeclaringEntityType.ClrType) + }, + new[] { new Tuple(property, property.DeclaringType) }); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1936,23 +1843,19 @@ public static void DetectChangesStarting( { var definition = CoreResources.LogDetectChangesStarting(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - context.GetType().ShortDisplayName()); + definition.Log(diagnostics, context.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextEventData( - definition, - DetectChangesStarting, - context)); + var eventData = new DbContextEventData( + definition, + DetectChangesStarting, + context); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -1974,23 +1877,19 @@ public static void DetectChangesCompleted( { var definition = CoreResources.LogDetectChangesCompleted(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - context.GetType().ShortDisplayName()); + definition.Log(diagnostics,context.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextEventData( - definition, - DetectChangesCompleted, - context)); + var eventData = new DbContextEventData( + definition, + DetectChangesCompleted, + context); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2018,27 +1917,22 @@ public static void PropertyChangeDetected( { var definition = CoreResources.LogPropertyChangeDetected(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - property.DeclaringEntityType.ShortName(), - property.Name); + definition.Log(diagnostics,property.DeclaringEntityType.ShortName(),property.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyChangedEventData( - definition, - PropertyChangeDetected, - new EntityEntry(internalEntityEntry), - property, - oldValue, - newValue)); + var eventData = new PropertyChangedEventData( + definition, + PropertyChangeDetected, + new EntityEntry(internalEntityEntry), + property, + oldValue, + newValue); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2068,12 +1962,10 @@ public static void PropertyChangeDetectedSensitive( { var definition = CoreResources.LogPropertyChangeDetectedSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, property.DeclaringEntityType.ShortName(), property.Name, oldValue, @@ -2081,17 +1973,17 @@ public static void PropertyChangeDetectedSensitive( internalEntityEntry.BuildCurrentValuesString(property.DeclaringEntityType.FindPrimaryKey().Properties)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyChangedEventData( - definition, - PropertyChangeDetectedSensitive, - new EntityEntry(internalEntityEntry), - property, - oldValue, - newValue)); + var eventData = new PropertyChangedEventData( + definition, + PropertyChangeDetectedSensitive, + new EntityEntry(internalEntityEntry), + property, + oldValue, + newValue); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2124,27 +2016,25 @@ public static void ForeignKeyChangeDetected( { var definition = CoreResources.LogForeignKeyChangeDetected(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, property.DeclaringEntityType.ShortName(), property.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyChangedEventData( - definition, - ForeignKeyChangeDetected, - new EntityEntry(internalEntityEntry), - property, - oldValue, - newValue)); + var eventData = new PropertyChangedEventData( + definition, + ForeignKeyChangeDetected, + new EntityEntry(internalEntityEntry), + property, + oldValue, + newValue); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2174,12 +2064,10 @@ public static void ForeignKeyChangeDetectedSensitive( { var definition = CoreResources.LogForeignKeyChangeDetectedSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, property.DeclaringEntityType.ShortName(), property.Name, oldValue, @@ -2187,17 +2075,17 @@ public static void ForeignKeyChangeDetectedSensitive( internalEntityEntry.BuildCurrentValuesString(property.DeclaringEntityType.FindPrimaryKey().Properties)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyChangedEventData( - definition, - ForeignKeyChangeDetectedSensitive, - new EntityEntry(internalEntityEntry), - property, - oldValue, - newValue)); + var eventData = new PropertyChangedEventData( + definition, + ForeignKeyChangeDetectedSensitive, + new EntityEntry(internalEntityEntry), + property, + oldValue, + newValue); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2230,29 +2118,27 @@ public static void CollectionChangeDetected( { var definition = CoreResources.LogCollectionChangeDetected(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, added.Count, removed.Count, navigation.DeclaringEntityType.ShortName(), navigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new CollectionChangedEventData( - definition, - CollectionChangeDetected, - new EntityEntry(internalEntityEntry), - navigation, - added, - removed)); + var eventData = new CollectionChangedEventData( + definition, + CollectionChangeDetected, + new EntityEntry(internalEntityEntry), + navigation, + added, + removed); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2284,12 +2170,10 @@ public static void CollectionChangeDetectedSensitive( { var definition = CoreResources.LogCollectionChangeDetectedSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, added.Count, removed.Count, navigation.DeclaringEntityType.ShortName(), @@ -2297,17 +2181,17 @@ public static void CollectionChangeDetectedSensitive( internalEntityEntry.BuildCurrentValuesString(navigation.DeclaringEntityType.FindPrimaryKey().Properties)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new CollectionChangedEventData( - definition, - CollectionChangeDetectedSensitive, - new EntityEntry(internalEntityEntry), - navigation, - added, - removed)); + var eventData = new CollectionChangedEventData( + definition, + CollectionChangeDetectedSensitive, + new EntityEntry(internalEntityEntry), + navigation, + added, + removed); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2340,27 +2224,22 @@ public static void ReferenceChangeDetected( { var definition = CoreResources.LogReferenceChangeDetected(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - navigation.DeclaringEntityType.ShortName(), - navigation.Name); + definition.Log(diagnostics,navigation.DeclaringEntityType.ShortName(),navigation.Name); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ReferenceChangedEventData( - definition, - ReferenceChangeDetected, - new EntityEntry(internalEntityEntry), - navigation, - oldValue, - newValue)); + var eventData = new ReferenceChangedEventData( + definition, + ReferenceChangeDetected, + new EntityEntry(internalEntityEntry), + navigation, + oldValue, + newValue); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2390,28 +2269,26 @@ public static void ReferenceChangeDetectedSensitive( { var definition = CoreResources.LogReferenceChangeDetectedSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, navigation.DeclaringEntityType.ShortName(), navigation.Name, internalEntityEntry.BuildCurrentValuesString(navigation.DeclaringEntityType.FindPrimaryKey().Properties)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new ReferenceChangedEventData( - definition, - ReferenceChangeDetectedSensitive, - new EntityEntry(internalEntityEntry), - navigation, - oldValue, - newValue)); + var eventData = new ReferenceChangedEventData( + definition, + ReferenceChangeDetectedSensitive, + new EntityEntry(internalEntityEntry), + navigation, + oldValue, + newValue); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2436,24 +2313,22 @@ public static void StartedTracking( { var definition = CoreResources.LogStartedTracking(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalEntityEntry.StateManager.Context.GetType().ShortDisplayName(), internalEntityEntry.EntityType.ShortName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new EntityEntryEventData( - definition, - StartedTracking, - new EntityEntry(internalEntityEntry))); + var eventData = new EntityEntryEventData( + definition, + StartedTracking, + new EntityEntry(internalEntityEntry)); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2477,25 +2352,23 @@ public static void StartedTrackingSensitive( { var definition = CoreResources.LogStartedTrackingSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalEntityEntry.StateManager.Context.GetType().ShortDisplayName(), internalEntityEntry.EntityType.ShortName(), internalEntityEntry.BuildCurrentValuesString(internalEntityEntry.EntityType.FindPrimaryKey().Properties)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new EntityEntryEventData( - definition, - StartedTrackingSensitive, - new EntityEntry(internalEntityEntry))); + var eventData = new EntityEntryEventData( + definition, + StartedTrackingSensitive, + new EntityEntry(internalEntityEntry)); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2524,28 +2397,26 @@ public static void StateChanged( { var definition = CoreResources.LogStateChanged(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalEntityEntry.EntityType.ShortName(), internalEntityEntry.StateManager.Context.GetType().ShortDisplayName(), oldState, newState); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new StateChangedEventData( - definition, - StateChanged, - new EntityEntry(internalEntityEntry), - oldState, - newState)); + var eventData = new StateChangedEventData( + definition, + StateChanged, + new EntityEntry(internalEntityEntry), + oldState, + newState); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2575,12 +2446,10 @@ public static void StateChangedSensitive( { var definition = CoreResources.LogStateChangedSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalEntityEntry.EntityType.ShortName(), internalEntityEntry.BuildCurrentValuesString(internalEntityEntry.EntityType.FindPrimaryKey().Properties), internalEntityEntry.StateManager.Context.GetType().ShortDisplayName(), @@ -2588,16 +2457,16 @@ public static void StateChangedSensitive( newState); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new StateChangedEventData( - definition, - StateChangedSensitive, - new EntityEntry(internalEntityEntry), - oldState, - newState)); + var eventData = new StateChangedEventData( + definition, + StateChangedSensitive, + new EntityEntry(internalEntityEntry), + oldState, + newState); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2632,27 +2501,25 @@ public static void ValueGenerated( ? CoreResources.LogTempValueGenerated(diagnostics) : CoreResources.LogValueGenerated(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalEntityEntry.StateManager.Context.GetType().ShortDisplayName(), property.Name, internalEntityEntry.EntityType.ShortName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyValueEventData( - definition, - ValueGenerated, - new EntityEntry(internalEntityEntry), - property, - value)); + var eventData = new PropertyValueEventData( + definition, + ValueGenerated, + new EntityEntry(internalEntityEntry), + property, + value); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2685,28 +2552,26 @@ public static void ValueGeneratedSensitive( ? CoreResources.LogTempValueGeneratedSensitive(diagnostics) : CoreResources.LogValueGeneratedSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalEntityEntry.StateManager.Context.GetType().ShortDisplayName(), value, property.Name, internalEntityEntry.EntityType.ShortName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new PropertyValueEventData( - definition, - ValueGeneratedSensitive, - new EntityEntry(internalEntityEntry), - property, - value)); + var eventData = new PropertyValueEventData( + definition, + ValueGeneratedSensitive, + new EntityEntry(internalEntityEntry), + property, + value); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2736,27 +2601,25 @@ public static void CascadeDelete( { var definition = CoreResources.LogCascadeDelete(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalChildEntry.EntityType.ShortName(), state, internalParentEntry.EntityType.ShortName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new CascadeDeleteEventData( - definition, - CascadeDelete, - new EntityEntry(internalChildEntry), - new EntityEntry(internalParentEntry), - state)); + var eventData = new CascadeDeleteEventData( + definition, + CascadeDelete, + new EntityEntry(internalChildEntry), + new EntityEntry(internalParentEntry), + state); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2785,12 +2648,10 @@ public static void CascadeDeleteSensitive( { var definition = CoreResources.LogCascadeDeleteSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalChildEntry.EntityType.ShortName(), internalChildEntry.BuildCurrentValuesString(internalChildEntry.EntityType.FindPrimaryKey().Properties), state, @@ -2798,16 +2659,16 @@ public static void CascadeDeleteSensitive( internalParentEntry.BuildCurrentValuesString(internalParentEntry.EntityType.FindPrimaryKey().Properties)); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new CascadeDeleteEventData( - definition, - CascadeDeleteSensitive, - new EntityEntry(internalChildEntry), - new EntityEntry(internalParentEntry), - state)); + var eventData = new CascadeDeleteEventData( + definition, + CascadeDeleteSensitive, + new EntityEntry(internalChildEntry), + new EntityEntry(internalParentEntry), + state); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2838,27 +2699,25 @@ public static void CascadeDeleteOrphan( { var definition = CoreResources.LogCascadeDeleteOrphan(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalChildEntry.EntityType.ShortName(), state, parentEntityType.ShortName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new CascadeDeleteOrphanEventData( - definition, - CascadeDeleteOrphan, - new EntityEntry(internalChildEntry), - parentEntityType, - state)); + var eventData = new CascadeDeleteOrphanEventData( + definition, + CascadeDeleteOrphan, + new EntityEntry(internalChildEntry), + parentEntityType, + state); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2887,28 +2746,26 @@ public static void CascadeDeleteOrphanSensitive( { var definition = CoreResources.LogCascadeDeleteOrphanSensitive(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { definition.Log( diagnostics, - warningBehavior, internalChildEntry.EntityType.ShortName(), internalChildEntry.BuildCurrentValuesString(internalChildEntry.EntityType.FindPrimaryKey().Properties), state, parentEntityType.ShortName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new CascadeDeleteOrphanEventData( - definition, - CascadeDeleteOrphanSensitive, - new EntityEntry(internalChildEntry), - parentEntityType, - state)); + var eventData = new CascadeDeleteOrphanEventData( + definition, + CascadeDeleteOrphanSensitive, + new EntityEntry(internalChildEntry), + parentEntityType, + state); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2934,23 +2791,19 @@ public static void SaveChangesStarting( { var definition = CoreResources.LogSaveChangesStarting(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - context.GetType().ShortDisplayName()); + definition.Log(diagnostics,context.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextEventData( - definition, - SaveChangesStarting, - context)); + var eventData = new DbContextEventData( + definition, + SaveChangesStarting, + context); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -2974,25 +2827,19 @@ public static void SaveChangesCompleted( { var definition = CoreResources.LogSaveChangesCompleted(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) { - definition.Log( - diagnostics, - warningBehavior, - context.GetType().ShortDisplayName(), - entitiesSavedCount); + definition.Log(diagnostics,context.GetType().ShortDisplayName(), entitiesSavedCount); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new SaveChangesCompletedEventData( - definition, - SaveChangesCompleted, - context, - entitiesSavedCount)); + var eventData = new SaveChangesCompletedEventData( + definition, + SaveChangesCompleted, + context, + entitiesSavedCount); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } @@ -3016,23 +2863,19 @@ public static void ContextDisposed( { var definition = CoreResources.LogContextDisposed(diagnostics); - var warningBehavior = definition.GetLogBehavior(diagnostics); - if (warningBehavior != WarningBehavior.Ignore) + if (diagnostics.ShouldLog(definition)) { - definition.Log( - diagnostics, - warningBehavior, - context.GetType().ShortDisplayName()); + definition.Log(diagnostics,context.GetType().ShortDisplayName()); } - if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) { - diagnostics.DiagnosticSource.Write( - definition.EventId.Name, - new DbContextEventData( - definition, - ContextDisposed, - context)); + var eventData = new DbContextEventData( + definition, + ContextDisposed, + context); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } } diff --git a/src/EFCore/Diagnostics/DiagnosticsLoggerExtensions.cs b/src/EFCore/Diagnostics/DiagnosticsLoggerExtensions.cs new file mode 100644 index 00000000000..981028ab3af --- /dev/null +++ b/src/EFCore/Diagnostics/DiagnosticsLoggerExtensions.cs @@ -0,0 +1,128 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using JetBrains.Annotations; +using Microsoft.Extensions.Logging; + +namespace Microsoft.EntityFrameworkCore.Diagnostics +{ + /// + /// + /// Extensions on for use by database providers when logging events. + /// + /// + /// This type is typically used by database providers. It is generally not used in application code. + /// + /// + public static class DiagnosticsLoggerExtensions + { + /// + /// Checks whether or not the message should be sent to the . + /// + /// The being used. + /// The definition of the event to log. + /// True if logging is enabled and the event should not be ignored; false otherwise. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // Because hot path for logging + public static bool ShouldLog( + [NotNull] this IDiagnosticsLogger diagnostics, + [NotNull] EventDefinitionBase definition) + // No null checks; low-level code in hot path for logging. + => definition.WarningBehavior == WarningBehavior.Throw + || (diagnostics.Logger.IsEnabled(definition.Level) + && definition.WarningBehavior != WarningBehavior.Ignore); + + /// + /// Dispatches the given to a , if enabled, and + /// a , if enabled. + /// + /// The being used. + /// The definition of the event to log. + /// The event data. + /// True to dispatch to a ; false otherwise. + /// True to dispatch to a ; false otherwise. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // Because hot path for logging + public static void DispatchEventData( + [NotNull] this IDiagnosticsLogger diagnostics, + [NotNull] EventDefinitionBase definition, + [NotNull] EventData eventData, + bool diagnosticSourceEnabled, + bool simpleLogEnabled) + { + // No null checks; low-level code in hot path for logging. + + if (diagnosticSourceEnabled) + { + diagnostics.DiagnosticSource.Write(definition.EventId.Name, eventData); + } + + if (simpleLogEnabled) + { + diagnostics.SimpleLogger.Log(eventData); + } + } + + /// + /// Determines whether or not an instance is needed based on whether or + /// not there is a or an enabled for + /// the given event. + /// + /// The being used. + /// The definition of the event. + /// Set to true if a is enabled; false otherwise. + /// True to true if a is enabled; false otherwise. + /// True if either a diagnostic source or a simple logger is enabled; false otherwise. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // Because hot path for logging + public static bool NeedsEventData( + [NotNull] this IDiagnosticsLogger diagnostics, + [NotNull] EventDefinitionBase definition, + out bool diagnosticSourceEnabled, + out bool simpleLogEnabled) + { + // No null checks; low-level code in hot path for logging. + + diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); + + simpleLogEnabled = definition.WarningBehavior == WarningBehavior.Log + && diagnostics.SimpleLogger.ShouldLog(definition.EventId, definition.Level); + + return diagnosticSourceEnabled + || simpleLogEnabled; + } + + /// + /// Determines whether or not an instance is needed based on whether or + /// not there is a , an , or an enabled for + /// the given event. + /// + /// The being used. + /// The definition of the event. + /// The to use if enabled; otherwise null. + /// Set to true if a is enabled; false otherwise. + /// True to true if a is enabled; false otherwise. + /// True if either a diagnostic source, a simple logger, or an interceptor is enabled; false otherwise. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // Because hot path for logging + public static bool NeedsEventData( + [NotNull] this IDiagnosticsLogger diagnostics, + [NotNull] EventDefinitionBase definition, + [CanBeNull] out TInterceptor interceptor, + out bool diagnosticSourceEnabled, + out bool simpleLogEnabled) + where TInterceptor : class, IInterceptor + { + // No null checks; low-level code in hot path for logging. + + diagnosticSourceEnabled = diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name); + + interceptor = diagnostics.Interceptors?.Aggregate(); + + simpleLogEnabled = definition.WarningBehavior == WarningBehavior.Log + && diagnostics.SimpleLogger.ShouldLog(definition.EventId, definition.Level); + + return diagnosticSourceEnabled + || simpleLogEnabled + || interceptor != null; + } + } +} diff --git a/src/EFCore/Diagnostics/EventData.cs b/src/EFCore/Diagnostics/EventData.cs index 65692ae7069..c21a15a6cc5 100644 --- a/src/EFCore/Diagnostics/EventData.cs +++ b/src/EFCore/Diagnostics/EventData.cs @@ -39,6 +39,11 @@ public EventData( /// public virtual LogLevel LogLevel => _eventDefinition.Level; + /// + /// A string representing the code where this event is defined. + /// + public virtual string EventIdCode => _eventDefinition.EventIdCode; + /// /// A logger message describing this event. /// diff --git a/src/EFCore/Diagnostics/EventDefinition.cs b/src/EFCore/Diagnostics/EventDefinition.cs index 40f7df7c1a0..e2e71c40eb6 100644 --- a/src/EFCore/Diagnostics/EventDefinition.cs +++ b/src/EFCore/Diagnostics/EventDefinition.cs @@ -56,18 +56,16 @@ public virtual string GenerateMessage() /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// Optional exception associated with the event. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] Exception exception = null) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: - _logAction(logger.Logger, null); + _logAction(logger.Logger, exception); break; case WarningBehavior.Throw: throw WarningAsError(GenerateMessage()); diff --git a/src/EFCore/Diagnostics/EventDefinitionBase.cs b/src/EFCore/Diagnostics/EventDefinitionBase.cs index c527a8f377f..cc3ec0c0740 100644 --- a/src/EFCore/Diagnostics/EventDefinitionBase.cs +++ b/src/EFCore/Diagnostics/EventDefinitionBase.cs @@ -14,8 +14,6 @@ namespace Microsoft.EntityFrameworkCore.Diagnostics /// public abstract class EventDefinitionBase { - private readonly WarningBehavior _warningBehavior; - /// /// Creates an event definition instance. /// @@ -48,7 +46,7 @@ protected EventDefinitionBase( } var behavior = warningsConfiguration.GetBehavior(eventId); - _warningBehavior = behavior + WarningBehavior = behavior ?? (level == LogLevel.Warning && warningsConfiguration.DefaultBehavior == WarningBehavior.Throw ? WarningBehavior.Throw @@ -56,7 +54,7 @@ protected EventDefinitionBase( } else { - _warningBehavior = WarningBehavior.Log; + WarningBehavior = WarningBehavior.Log; } Level = level; @@ -87,17 +85,9 @@ protected virtual Exception WarningAsError([NotNull] string message) CoreStrings.WarningAsErrorTemplate(EventId.ToString(), message, EventIdCode)); /// - /// Gets the log behavior for this event. This determines whether it should be logged, thrown as an exception or ignored. + /// The configured . /// - /// The . - /// The logger to which the event would be logged. - /// Whether the event should be logged, thrown as an exception or ignored. - public virtual WarningBehavior GetLogBehavior( - [NotNull] IDiagnosticsLogger logger) - where TLoggerCategory : LoggerCategory, new() - => _warningBehavior == WarningBehavior.Log - ? logger.Logger.IsEnabled(Level) ? WarningBehavior.Log : WarningBehavior.Ignore - : _warningBehavior; + public virtual WarningBehavior WarningBehavior { get; } internal sealed class MessageExtractingLogger : ILogger { diff --git a/src/EFCore/Diagnostics/EventDefinition`.cs b/src/EFCore/Diagnostics/EventDefinition`.cs index e46c356e324..27b2dd9b9c9 100644 --- a/src/EFCore/Diagnostics/EventDefinition`.cs +++ b/src/EFCore/Diagnostics/EventDefinition`.cs @@ -58,15 +58,13 @@ public virtual string GenerateMessage( /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// Message argument. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] TParam arg) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: _logAction(logger.Logger, arg, null); diff --git a/src/EFCore/Diagnostics/EventDefinition``.cs b/src/EFCore/Diagnostics/EventDefinition``.cs index 3ef444b07c9..ca033c72fc1 100644 --- a/src/EFCore/Diagnostics/EventDefinition``.cs +++ b/src/EFCore/Diagnostics/EventDefinition``.cs @@ -60,17 +60,15 @@ public virtual string GenerateMessage( /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// The first message argument. /// The second message argument. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] TParam1 arg1, [CanBeNull] TParam2 arg2) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: _logAction(logger.Logger, arg1, arg2, null); diff --git a/src/EFCore/Diagnostics/EventDefinition```.cs b/src/EFCore/Diagnostics/EventDefinition```.cs index 1d2544326c4..7f0ec3e21b9 100644 --- a/src/EFCore/Diagnostics/EventDefinition```.cs +++ b/src/EFCore/Diagnostics/EventDefinition```.cs @@ -64,21 +64,19 @@ public virtual string GenerateMessage( /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// The first message argument. /// The second message argument. /// The third message argument. /// Optional exception associated with the event. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] TParam1 arg1, [CanBeNull] TParam2 arg2, [CanBeNull] TParam3 arg3, [CanBeNull] Exception exception = null) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: _logAction(logger.Logger, arg1, arg2, arg3, exception); diff --git a/src/EFCore/Diagnostics/EventDefinition````.cs b/src/EFCore/Diagnostics/EventDefinition````.cs index 4f1cd2789bc..a5d9b0c6121 100644 --- a/src/EFCore/Diagnostics/EventDefinition````.cs +++ b/src/EFCore/Diagnostics/EventDefinition````.cs @@ -64,21 +64,19 @@ public virtual string GenerateMessage( /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// The first message argument. /// The second message argument. /// The third message argument. /// The fourth message argument. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] TParam1 arg1, [CanBeNull] TParam2 arg2, [CanBeNull] TParam3 arg3, [CanBeNull] TParam4 arg4) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: _logAction(logger.Logger, arg1, arg2, arg3, arg4, null); diff --git a/src/EFCore/Diagnostics/EventDefinition`````.cs b/src/EFCore/Diagnostics/EventDefinition`````.cs index ce84de3ce2c..065f8a50d24 100644 --- a/src/EFCore/Diagnostics/EventDefinition`````.cs +++ b/src/EFCore/Diagnostics/EventDefinition`````.cs @@ -66,7 +66,6 @@ public virtual string GenerateMessage( /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// The first message argument. /// The second message argument. /// The third message argument. @@ -74,7 +73,6 @@ public virtual string GenerateMessage( /// The fifth message argument. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] TParam1 arg1, [CanBeNull] TParam2 arg2, [CanBeNull] TParam3 arg3, @@ -82,7 +80,7 @@ public virtual void Log( [CanBeNull] TParam5 arg5) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: _logAction(logger.Logger, arg1, arg2, arg3, arg4, arg5, null); diff --git a/src/EFCore/Diagnostics/EventDefinition``````.cs b/src/EFCore/Diagnostics/EventDefinition``````.cs index ff9b3ab3e02..6b8be6211cd 100644 --- a/src/EFCore/Diagnostics/EventDefinition``````.cs +++ b/src/EFCore/Diagnostics/EventDefinition``````.cs @@ -68,7 +68,6 @@ public virtual string GenerateMessage( /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// The first message argument. /// The second message argument. /// The third message argument. @@ -77,7 +76,6 @@ public virtual string GenerateMessage( /// The sixth message argument. public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [CanBeNull] TParam1 arg1, [CanBeNull] TParam2 arg2, [CanBeNull] TParam3 arg3, @@ -86,7 +84,7 @@ public virtual void Log( [CanBeNull] TParam6 arg6) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: _logAction(logger.Logger, arg1, arg2, arg3, arg4, arg5, arg6, null); diff --git a/src/EFCore/Diagnostics/FallbackEventDefinition.cs b/src/EFCore/Diagnostics/FallbackEventDefinition.cs index df1f6f786a3..5b4e635573c 100644 --- a/src/EFCore/Diagnostics/FallbackEventDefinition.cs +++ b/src/EFCore/Diagnostics/FallbackEventDefinition.cs @@ -57,15 +57,13 @@ public virtual string GenerateMessage([NotNull] Action logAction) /// /// The . /// The logger to which the event should be logged. - /// Whether the event should be logged, thrown as an exception or ignored. /// A delegate that will log the message to an . public virtual void Log( [NotNull] IDiagnosticsLogger logger, - WarningBehavior warningBehavior, [NotNull] Action logAction) where TLoggerCategory : LoggerCategory, new() { - switch (warningBehavior) + switch (WarningBehavior) { case WarningBehavior.Log: logAction(logger.Logger); diff --git a/src/EFCore/Diagnostics/IDiagnosticsLogger.cs b/src/EFCore/Diagnostics/IDiagnosticsLogger.cs index a772d754345..b657e10a930 100644 --- a/src/EFCore/Diagnostics/IDiagnosticsLogger.cs +++ b/src/EFCore/Diagnostics/IDiagnosticsLogger.cs @@ -47,5 +47,15 @@ public interface IDiagnosticsLogger /// The . /// DiagnosticSource DiagnosticSource { get; } + + /// + /// The . + /// + ISimpleLogger SimpleLogger { get; } + + /// + /// Holds registered interceptors, if any. + /// + IInterceptors Interceptors { get; } } } diff --git a/src/EFCore/Diagnostics/IDiagnosticsLogger`.cs b/src/EFCore/Diagnostics/IDiagnosticsLogger`.cs index 5b043f95a52..b45717c9bcf 100644 --- a/src/EFCore/Diagnostics/IDiagnosticsLogger`.cs +++ b/src/EFCore/Diagnostics/IDiagnosticsLogger`.cs @@ -28,9 +28,5 @@ namespace Microsoft.EntityFrameworkCore.Diagnostics public interface IDiagnosticsLogger : IDiagnosticsLogger where TLoggerCategory : LoggerCategory, new() { - /// - /// Holds registered interceptors, if any. - /// - IInterceptors Interceptors { get; } } } diff --git a/src/EFCore/Diagnostics/ISimpleLogger.cs b/src/EFCore/Diagnostics/ISimpleLogger.cs new file mode 100644 index 00000000000..be7b9b4a4c3 --- /dev/null +++ b/src/EFCore/Diagnostics/ISimpleLogger.cs @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using JetBrains.Annotations; +using Microsoft.Extensions.Logging; + +namespace Microsoft.EntityFrameworkCore.Diagnostics +{ + /// + /// A simple logging interface for Entity Framework events. + /// Used by + /// + public interface ISimpleLogger + { + /// + /// + /// Logs the given . + /// + /// + /// This method is only called if returns true. + /// + /// + /// The specific subtype of the argument is dependent on the event + /// being logged. See for the type of event data used for each core event. + /// + /// + /// The event to log. + void Log([NotNull] EventData eventData); + + /// + /// Determines whether or not the given event should be logged. + /// + /// The ID of the event. + /// The level of the event. + /// Returns true if the event should be logged; false if it should be filtered out. + bool ShouldLog(EventId eventId, LogLevel logLevel); + } +} diff --git a/src/EFCore/Diagnostics/Internal/NullSimpleLogger.cs b/src/EFCore/Diagnostics/Internal/NullSimpleLogger.cs new file mode 100644 index 00000000000..89205a80859 --- /dev/null +++ b/src/EFCore/Diagnostics/Internal/NullSimpleLogger.cs @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Logging; + +namespace Microsoft.EntityFrameworkCore.Diagnostics.Internal +{ + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public class NullSimpleLogger : ISimpleLogger + { + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual void Log(EventData eventData) + { + } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual bool ShouldLog(EventId eventId, LogLevel logLevel) => false; + } +} diff --git a/src/EFCore/Diagnostics/SimpleLogger.cs b/src/EFCore/Diagnostics/SimpleLogger.cs new file mode 100644 index 00000000000..aa9c48b0109 --- /dev/null +++ b/src/EFCore/Diagnostics/SimpleLogger.cs @@ -0,0 +1,136 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Text; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Utilities; +using Microsoft.Extensions.Logging; + +namespace Microsoft.EntityFrameworkCore.Diagnostics +{ + /// + /// An implementation of that will log filtered events to a given sink + /// with some control over formatting. + /// + public class SimpleLogger : ISimpleLogger + { + /// + /// Creates a new instance. + /// + /// The sink to which messages will be logged. + /// A delegate that returns true to log the message; false to filter it out. + /// Formatting options for log messages. + public SimpleLogger( + [NotNull] Action sink, + [NotNull] Func filter, + SimpleLoggerFormatOptions formatOptions) + { + FormatOptions = formatOptions; + Sink = sink; + Filter = filter; + } + + /// + /// The to used when formatting messages to log. + /// + public SimpleLoggerFormatOptions FormatOptions { get; } // Intentionally not virtual for perf + + /// + /// The sink to which messages are being logged. + /// + public Action Sink { get; } // Intentionally not virtual for perf + + /// + /// A delegate that returns true to log the message; false to filter it out. + /// + public Func Filter { get; } // Intentionally not virtual for perf + + /// + public virtual void Log(EventData eventData) + { + Check.NotNull(eventData, nameof(eventData)); + + var message = eventData.ToString(); + var logLevel = eventData.LogLevel; + var eventId = eventData.EventId; + + if (FormatOptions != SimpleLoggerFormatOptions.None) + { + var messageBuilder = new StringBuilder(); + + if ((FormatOptions & SimpleLoggerFormatOptions.Level) != 0) + { + messageBuilder.Append(GetLogLevelString(logLevel)); + } + + if ((FormatOptions & SimpleLoggerFormatOptions.LocalTime) != 0) + { + messageBuilder.Append(DateTime.Now.ToShortDateString()).Append(DateTime.Now.ToString(" HH:mm:ss.fff ")); + } + + if ((FormatOptions & SimpleLoggerFormatOptions.UtcTime) != 0) + { + messageBuilder.Append(DateTime.UtcNow.ToString("o")).Append(' '); + } + + if ((FormatOptions & SimpleLoggerFormatOptions.Id) != 0) + { + messageBuilder.Append(eventData.EventIdCode).Append('[').Append(eventId.Id).Append("] "); + } + + if ((FormatOptions & SimpleLoggerFormatOptions.Category) != 0) + { + var lastDot = eventId.Name.LastIndexOf('.'); + if (lastDot > 0) + { + messageBuilder.Append('(').Append(eventId.Name.Substring(0, lastDot)).Append(") "); + } + } + + const string padding = " "; + var preambleLength = messageBuilder.Length; + + if (FormatOptions == SimpleLoggerFormatOptions.SingleLine) // Single line ONLY + { + message = messageBuilder + .Append(message) + .Replace(Environment.NewLine, "") + .ToString(); + } + else + { + message = (FormatOptions & SimpleLoggerFormatOptions.SingleLine) != 0 + ? messageBuilder + .Append("-> ") + .Append(message) + .Replace(Environment.NewLine, "", preambleLength, messageBuilder.Length - preambleLength) + .ToString() + : messageBuilder + .AppendLine() + .Append(message) + .Replace(Environment.NewLine, Environment.NewLine + padding, preambleLength, messageBuilder.Length - preambleLength) + .ToString(); + } + } + + Sink(message); + } + + /// + public virtual bool ShouldLog(EventId eventId, LogLevel logLevel) + => Filter(eventId, logLevel); + + private static string GetLogLevelString(LogLevel logLevel) + => logLevel switch + { + LogLevel.Trace => "trce: ", + LogLevel.Debug => "dbug: ", + LogLevel.Information => "info: ", + LogLevel.Warning => "warn: ", + LogLevel.Error => "fail: ", + LogLevel.Critical => "crit: ", + _ => "none", + }; + } +} diff --git a/src/EFCore/Diagnostics/SimpleLoggerFormatOptions.cs b/src/EFCore/Diagnostics/SimpleLoggerFormatOptions.cs new file mode 100644 index 00000000000..68a7462f3fe --- /dev/null +++ b/src/EFCore/Diagnostics/SimpleLoggerFormatOptions.cs @@ -0,0 +1,73 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.EntityFrameworkCore.Diagnostics +{ + /// + /// Formatting options for use with + /// and . + /// + [Flags] + public enum SimpleLoggerFormatOptions + { + /// + /// The raw log message with no additional metadata or formatting. + /// + None = 0, + + /// + /// Each event will only occupy a single line in the log. Multiple lines are used by default. + /// + SingleLine = 1, + + /// + /// Include the event in each log message. The level is included by default. + /// + Level = 1 << 1, + + /// + /// Includes the event in each message. The category is included by default. + /// + Category = 1 << 2, + + /// + /// Includes the in each message. The event ID is included by default. + /// + Id = 1 << 3, + + /// + /// Includes a UTC timestamp in each message. The local time is included by default. Use + /// to include all default options but change timestamps to UTC. + /// + UtcTime = 1 << 4, + + /// + /// Includes a local time timestamp in each message. The local time is included by default. + /// + LocalTime = 1 << 5, + + /// + /// + /// The default used by . + /// + /// + /// Includes , , , . + /// + /// + DefaultWithLocalTime = Level | Category | Id | LocalTime, + + /// + /// + /// The same defaults as used by , + /// but with UTC timestamps. + /// + /// + /// Includes , , , . + /// + /// + DefaultWithUtcTime = Level | Category | Id | UtcTime + } +} diff --git a/src/EFCore/Infrastructure/CoreOptionsExtension.cs b/src/EFCore/Infrastructure/CoreOptionsExtension.cs index bd1ec68f448..d5a588e717d 100644 --- a/src/EFCore/Infrastructure/CoreOptionsExtension.cs +++ b/src/EFCore/Infrastructure/CoreOptionsExtension.cs @@ -33,6 +33,7 @@ public class CoreOptionsExtension : IDbContextOptionsExtension private IServiceProvider _applicationServiceProvider; private IModel _model; private ILoggerFactory _loggerFactory; + private ISimpleLogger _simpleLogger; private IMemoryCache _memoryCache; private bool _sensitiveDataLoggingEnabled; private bool _detailedErrorsEnabled; @@ -66,6 +67,7 @@ protected CoreOptionsExtension([NotNull] CoreOptionsExtension copyFrom) _applicationServiceProvider = copyFrom.ApplicationServiceProvider; _model = copyFrom.Model; _loggerFactory = copyFrom.LoggerFactory; + _simpleLogger = copyFrom.SimpleLogger; _memoryCache = copyFrom.MemoryCache; _sensitiveDataLoggingEnabled = copyFrom.IsSensitiveDataLoggingEnabled; _detailedErrorsEnabled = copyFrom.DetailedErrorsEnabled; @@ -168,6 +170,21 @@ public virtual CoreOptionsExtension WithLoggerFactory([CanBeNull] ILoggerFactory return clone; } + /// + /// Creates a new instance with all options the same as for this instance, but with the given option changed. + /// It is unusual to call this method directly. Instead use . + /// + /// The option to change. + /// A new instance with the option changed. + public virtual CoreOptionsExtension WithSimpleLogger([CanBeNull] ISimpleLogger simpleLogger) + { + var clone = Clone(); + + clone._simpleLogger = simpleLogger; + + return clone; + } + /// /// Creates a new instance with all options the same as for this instance, but with the given option changed. /// It is unusual to call this method directly. Instead use . @@ -318,6 +335,11 @@ public virtual CoreOptionsExtension WithInterceptors([NotNull] IEnumerable public virtual ILoggerFactory LoggerFactory => _loggerFactory; + /// + /// The option set from the method. + /// + public virtual ISimpleLogger SimpleLogger => _simpleLogger; + /// /// The option set from the method. /// diff --git a/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs b/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs index 970119f1c88..1e2340380fe 100644 --- a/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs +++ b/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs @@ -130,6 +130,7 @@ public static readonly IDictionary CoreServices { typeof(IDbContextTransactionManager), new ServiceCharacteristics(ServiceLifetime.Scoped) }, { typeof(IQueryContextFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) }, { typeof(IQueryCompilationContextFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) }, + { typeof(ISimpleLogger), new ServiceCharacteristics(ServiceLifetime.Scoped) }, { typeof(ILazyLoader), new ServiceCharacteristics(ServiceLifetime.Transient) }, { typeof(IParameterBindingFactory), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) @@ -265,6 +266,8 @@ public virtual EntityFrameworkServicesBuilder TryAddCoreServices() TryAdd(); TryAdd(); + TryAdd(p => p.GetService()?.FindExtension().SimpleLogger ?? new NullSimpleLogger()); + // This has to be lazy to avoid creating instances that are not disposed ServiceCollectionMap .TryAddSingleton(p => new DiagnosticListener(DbLoggerCategory.Name)); diff --git a/src/EFCore/Internal/DiagnosticsLogger.cs b/src/EFCore/Internal/DiagnosticsLogger.cs index f67d913b9d5..66316b154ef 100644 --- a/src/EFCore/Internal/DiagnosticsLogger.cs +++ b/src/EFCore/Internal/DiagnosticsLogger.cs @@ -37,10 +37,12 @@ public DiagnosticsLogger( [NotNull] ILoggingOptions loggingOptions, [NotNull] DiagnosticSource diagnosticSource, [NotNull] LoggingDefinitions loggingDefinitions, + [NotNull] ISimpleLogger simpleLogger, [CanBeNull] IInterceptors interceptors = null) { DiagnosticSource = diagnosticSource; Definitions = loggingDefinitions; + SimpleLogger = simpleLogger; Logger = loggerFactory.CreateLogger(new TLoggerCategory()); Options = loggingOptions; Interceptors = interceptors; @@ -86,6 +88,14 @@ public DiagnosticsLogger( /// public virtual LoggingDefinitions Definitions { get; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual ISimpleLogger SimpleLogger { get; } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore/Internal/ServiceProviderCache.cs b/src/EFCore/Internal/ServiceProviderCache.cs index c4188c920ad..0d8692541fa 100644 --- a/src/EFCore/Internal/ServiceProviderCache.cs +++ b/src/EFCore/Internal/ServiceProviderCache.cs @@ -8,6 +8,7 @@ using System.Linq; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; @@ -119,7 +120,8 @@ public virtual IServiceProvider GetOrAdd([NotNull] IDbContextOptions options, bo ScopedLoggerFactory.Create(scopedProvider, options), scopedProvider.GetService(), scopedProvider.GetService(), - loggingDefinitions); + loggingDefinitions, + new NullSimpleLogger()); if (_configurations.Count == 0) { diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs index 24d4eedff23..a824eebabf1 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs @@ -365,7 +365,7 @@ private static void RemoveIndex(IConventionIndex index) public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext context) { var definition = CoreResources.LogRedundantIndexRemoved(Dependencies.Logger); - if (definition.GetLogBehavior(Dependencies.Logger) == WarningBehavior.Ignore + if (!Dependencies.Logger.ShouldLog(definition) && !Dependencies.Logger.DiagnosticSource.IsEnabled(definition.EventId.Name)) { return; diff --git a/src/EFCore/Metadata/Internal/EntityTypePathComparer.cs b/src/EFCore/Metadata/Internal/EntityTypePathComparer.cs index 22a4f234f01..2985cf16fa4 100644 --- a/src/EFCore/Metadata/Internal/EntityTypePathComparer.cs +++ b/src/EFCore/Metadata/Internal/EntityTypePathComparer.cs @@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public class EntityTypePathComparer : IComparer, IEqualityComparer + public sealed class EntityTypePathComparer : IComparer, IEqualityComparer { private EntityTypePathComparer() { @@ -32,7 +32,7 @@ private EntityTypePathComparer() /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual int Compare(IEntityType x, IEntityType y) + public int Compare(IEntityType x, IEntityType y) { if (ReferenceEquals(x, y)) { @@ -91,6 +91,7 @@ public virtual int Compare(IEntityType x, IEntityType y) /// The first object of type T to compare. /// The second object of type T to compare. /// true if the specified objects are equal; otherwise, false. + // Intentionally not virtual public bool Equals(IEntityType x, IEntityType y) => Compare(x, y) == 0; /// @@ -99,7 +100,7 @@ public virtual int Compare(IEntityType x, IEntityType y) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual int GetHashCode(IEntityType entityType) + public int GetHashCode(IEntityType entityType) { var hash = new HashCode(); while (true) diff --git a/src/EFCore/Metadata/Internal/PropertyListComparer.cs b/src/EFCore/Metadata/Internal/PropertyListComparer.cs index a4826c6553d..eec3abf0e60 100644 --- a/src/EFCore/Metadata/Internal/PropertyListComparer.cs +++ b/src/EFCore/Metadata/Internal/PropertyListComparer.cs @@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public class PropertyListComparer : IComparer>, IEqualityComparer> + public sealed class PropertyListComparer : IComparer>, IEqualityComparer> { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -32,6 +32,7 @@ private PropertyListComparer() /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// + // Intentionally not virtual public int Compare(IReadOnlyList x, IReadOnlyList y) { var result = x.Count - y.Count; @@ -58,6 +59,7 @@ public int Compare(IReadOnlyList x, IReadOnlyList y) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// + // Intentionally not virtual public bool Equals(IReadOnlyList x, IReadOnlyList y) => Compare(x, y) == 0; @@ -67,6 +69,7 @@ public bool Equals(IReadOnlyList x, IReadOnlyList y) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// + // Intentionally not virtual public int GetHashCode(IReadOnlyList obj) { var hash = new HashCode(); diff --git a/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs b/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs index 0ffed7f060c..1988923c075 100644 --- a/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs +++ b/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs @@ -60,7 +60,7 @@ public virtual object GenerateCacheKey(Expression query, bool async) /// The query to get the cache key for. /// A value indicating whether the query will be executed asynchronously. /// The cache key. - protected CompiledQueryCacheKey GenerateCacheKeyCore([NotNull] Expression query, bool async) + protected CompiledQueryCacheKey GenerateCacheKeyCore([NotNull] Expression query, bool async) // Intentionally non-virtual => new CompiledQueryCacheKey( Check.NotNull(query, nameof(query)), Dependencies.Model, diff --git a/test/EFCore.InMemory.Tests/InMemoryTransactionManagerTest.cs b/test/EFCore.InMemory.Tests/InMemoryTransactionManagerTest.cs index a9a7f10ac7b..367756a09cd 100644 --- a/test/EFCore.InMemory.Tests/InMemoryTransactionManagerTest.cs +++ b/test/EFCore.InMemory.Tests/InMemoryTransactionManagerTest.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.InMemory.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.InMemory.Internal; using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; @@ -66,7 +67,8 @@ private static void AssertThrows(Action action) new ListLoggerFactory(l => false), options, new DiagnosticListener("Fake"), - new InMemoryLoggingDefinitions()); + new InMemoryLoggingDefinitions(), + new NullSimpleLogger()); return logger; } } diff --git a/test/EFCore.Relational.Tests/ApiConsistencyTest.cs b/test/EFCore.Relational.Tests/ApiConsistencyTest.cs index 2153074057c..6c47b4e9c59 100644 --- a/test/EFCore.Relational.Tests/ApiConsistencyTest.cs +++ b/test/EFCore.Relational.Tests/ApiConsistencyTest.cs @@ -3,10 +3,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; +using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; @@ -14,6 +16,16 @@ namespace Microsoft.EntityFrameworkCore { public class ApiConsistencyTest : ApiConsistencyTestBase { + public ApiConsistencyTest() + : base( + typeof(RelationalCompiledQueryCacheKeyGenerator) + .GetRuntimeMethods() + .Single( + m => m.Name == "GenerateCacheKeyCore" + && m.DeclaringType == typeof(RelationalCompiledQueryCacheKeyGenerator))) + { + } + private static readonly Type[] _fluentApiTypes = { typeof(RelationalForeignKeyBuilderExtensions), @@ -31,9 +43,6 @@ public class ApiConsistencyTest : ApiConsistencyTestBase protected override IEnumerable FluentApiTypes => _fluentApiTypes; - protected override bool ShouldHaveVirtualMethods(Type type) - => type.Name != "EntityShaper"; - protected override void AddServices(ServiceCollection serviceCollection) { new EntityFrameworkRelationalServicesBuilder(serviceCollection).TryAddCoreServices(); diff --git a/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs b/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs index de1a836b2e6..ed06d5dfb37 100644 --- a/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs +++ b/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs @@ -939,7 +939,8 @@ public async Task Logs_commands_without_parameter_values( logFactory, new FakeLoggingOptions(false), new DiagnosticListener("Fake"), - new TestRelationalLoggingDefinitions()); + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()); var relationalCommand = CreateRelationalCommand( commandText: "Logged Command", @@ -996,7 +997,8 @@ public async Task Logs_commands_parameter_values( logFactory, new FakeLoggingOptions(true), new DiagnosticListener("Fake"), - new TestRelationalLoggingDefinitions()); + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()); var relationalCommand = CreateRelationalCommand( commandText: "Logged Command", @@ -1053,7 +1055,8 @@ public async Task Reports_command_diagnostic( new ListLoggerFactory(), new FakeLoggingOptions(false), new ListDiagnosticSource(diagnostic), - new TestRelationalLoggingDefinitions()); + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()); var relationalCommand = CreateRelationalCommand( parameters: new[] @@ -1123,7 +1126,8 @@ public async Task Reports_command_diagnostic_on_exception( new ListLoggerFactory(), new FakeLoggingOptions(false), new ListDiagnosticSource(diagnostic), - new TestRelationalLoggingDefinitions()); + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()); var relationalCommand = CreateRelationalCommand( parameters: new[] diff --git a/test/EFCore.Relational.Tests/Storage/RelationalTransactionExtensionsTest.cs b/test/EFCore.Relational.Tests/Storage/RelationalTransactionExtensionsTest.cs index 2316ad9d9d0..4a0cfdd9237 100644 --- a/test/EFCore.Relational.Tests/Storage/RelationalTransactionExtensionsTest.cs +++ b/test/EFCore.Relational.Tests/Storage/RelationalTransactionExtensionsTest.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -36,7 +37,8 @@ public void GetDbTransaction_returns_the_DbTransaction() loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), - new TestRelationalLoggingDefinitions()), + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()), false); Assert.Equal(dbTransaction, transaction.GetDbTransaction()); diff --git a/test/EFCore.Relational.Tests/TestUtilities/FakeDiagnosticsLogger.cs b/test/EFCore.Relational.Tests/TestUtilities/FakeDiagnosticsLogger.cs index 2bad1258bb1..cb8612535ad 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/FakeDiagnosticsLogger.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/FakeDiagnosticsLogger.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Logging; @@ -20,6 +21,8 @@ public class FakeDiagnosticsLogger : IDiagnosticsLogger, ILogger public DiagnosticSource DiagnosticSource { get; } = new DiagnosticListener("Fake"); + public ISimpleLogger SimpleLogger { get; } = new NullSimpleLogger(); + public void Log( LogLevel logLevel, EventId eventId, diff --git a/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs b/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs index 24994d6fb10..f40b2f52111 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Storage; @@ -26,12 +27,14 @@ public FakeRelationalConnection(IDbContextOptions options = null) new LoggerFactory(), new LoggingOptions(), new DiagnosticListener("FakeDiagnosticListener"), - new TestRelationalLoggingDefinitions()), + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()), new DiagnosticsLogger( new LoggerFactory(), new LoggingOptions(), new DiagnosticListener("FakeDiagnosticListener"), - new TestRelationalLoggingDefinitions()), + new TestRelationalLoggingDefinitions(), + new NullSimpleLogger()), new NamedConnectionStringResolver(options ?? CreateOptions()), new RelationalTransactionFactory(new RelationalTransactionFactoryDependencies()), new CurrentDbContext(new FakeDbContext()))) diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs b/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs index d444f16ad33..8d39acd6181 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs @@ -32,5 +32,7 @@ public void Log( public ILogger Logger => this; public virtual LoggingDefinitions Definitions { get; } = new TDefinitions(); + + public IInterceptors Interceptors { get; } } } diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestLoggerBase.cs b/test/EFCore.Specification.Tests/TestUtilities/TestLoggerBase.cs index 279cc8f2ba4..fce1c5a6e14 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestLoggerBase.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestLoggerBase.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; namespace Microsoft.EntityFrameworkCore.TestUtilities @@ -13,6 +14,8 @@ public abstract class TestLoggerBase public EventId LoggedEvent { get; set; } public string Message { get; set; } + public ISimpleLogger SimpleLogger { get; } = new TestSimpleLogger(); + public DiagnosticSource DiagnosticSource { get; } = new TestDiagnosticSource(); } } diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestLogger`.cs b/test/EFCore.Specification.Tests/TestUtilities/TestLogger`.cs index b5499345566..e9324d85851 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestLogger`.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestLogger`.cs @@ -9,6 +9,5 @@ public class TestLogger : TestLogger, IDi where TCategory : LoggerCategory, new() where TDefinitions : LoggingDefinitions, new() { - public IInterceptors Interceptors { get; } } } diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestSimpleLogger.cs b/test/EFCore.Specification.Tests/TestUtilities/TestSimpleLogger.cs new file mode 100644 index 00000000000..4a25d4bbc3b --- /dev/null +++ b/test/EFCore.Specification.Tests/TestUtilities/TestSimpleLogger.cs @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Microsoft.EntityFrameworkCore.TestUtilities +{ + public class TestSimpleLogger : ISimpleLogger + { + public LogLevel? LoggedAt { get; set; } + public EventId LoggedEvent { get; set; } + + public void Log(EventData eventData) + { + LoggedAt = eventData.LogLevel; + LoggedEvent = eventData.EventId; + } + + public bool ShouldLog(EventId eventId, LogLevel logLevel) => true; + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs index df5aef0cc74..24ce3e54da7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Linq; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -2201,7 +2202,8 @@ private void Test( Fixture.ListLoggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), - new SqlServerLoggingDefinitions())); + new SqlServerLoggingDefinitions(), + new NullSimpleLogger())); var databaseModel = databaseModelFactory.Create( Fixture.TestStore.ConnectionString, diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs index 5bbee2c208a..22c61306907 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Scaffolding; @@ -21,7 +22,8 @@ protected override IDatabaseModelFactory CreateDatabaseModelFactory(ILoggerFacto loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), - new SqlServerLoggingDefinitions())); + new SqlServerLoggingDefinitions(), + new NullSimpleLogger())); protected override bool AcceptTable(DatabaseTable table) => !(table is DatabaseView); diff --git a/test/EFCore.SqlServer.Tests/SqlServerConnectionTest.cs b/test/EFCore.SqlServer.Tests/SqlServerConnectionTest.cs index a305d4f1fb4..fb7a530454d 100644 --- a/test/EFCore.SqlServer.Tests/SqlServerConnectionTest.cs +++ b/test/EFCore.SqlServer.Tests/SqlServerConnectionTest.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; @@ -71,12 +72,14 @@ public static RelationalConnectionDependencies CreateDependencies(DbContextOptio new LoggerFactory(), new LoggingOptions(), new DiagnosticListener("FakeDiagnosticListener"), - new SqlServerLoggingDefinitions()), + new SqlServerLoggingDefinitions(), + new NullSimpleLogger()), new DiagnosticsLogger( new LoggerFactory(), new LoggingOptions(), new DiagnosticListener("FakeDiagnosticListener"), - new SqlServerLoggingDefinitions()), + new SqlServerLoggingDefinitions(), + new NullSimpleLogger()), new NamedConnectionStringResolver(options), new RelationalTransactionFactory(new RelationalTransactionFactoryDependencies()), new CurrentDbContext(new FakeDbContext())); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs index 1e64115707d..a490b12c51a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Linq; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; @@ -49,8 +50,11 @@ private void Test( .AddSingleton() .AddSingleton(typeof(IDiagnosticsLogger<>), typeof(DiagnosticsLogger<>)) .AddSingleton() - .AddSingleton(Fixture.ListLoggerFactory); + .AddSingleton(Fixture.ListLoggerFactory) + .AddSingleton(); + new SqliteDesignTimeServices().ConfigureDesignTimeServices(services); + var databaseModelFactory = services .BuildServiceProvider() .GetRequiredService(); diff --git a/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteDatabaseCleaner.cs b/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteDatabaseCleaner.cs index 84b4db66f5c..7a0065490f0 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteDatabaseCleaner.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteDatabaseCleaner.cs @@ -28,6 +28,7 @@ protected override IDatabaseModelFactory CreateDatabaseModelFactory(ILoggerFacto .AddSingleton() .AddSingleton(new DiagnosticListener(DbLoggerCategory.Name)) .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton(typeof(IDiagnosticsLogger<>), typeof(DiagnosticsLogger<>)) .AddSingleton() diff --git a/test/EFCore.Tests/ApiConsistencyTest.cs b/test/EFCore.Tests/ApiConsistencyTest.cs index e1d19f48ffc..9fb45ab3b64 100644 --- a/test/EFCore.Tests/ApiConsistencyTest.cs +++ b/test/EFCore.Tests/ApiConsistencyTest.cs @@ -3,12 +3,15 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.DependencyInjection; // ReSharper disable InconsistentNaming @@ -16,6 +19,18 @@ namespace Microsoft.EntityFrameworkCore { public class ApiConsistencyTest : ApiConsistencyTestBase { + public ApiConsistencyTest() + : base( + typeof(CompiledQueryCacheKeyGenerator).GetRuntimeMethods().Single(m => m.Name == "GenerateCacheKeyCore"), + typeof(InternalEntityEntry).GetRuntimeMethods().Single(m => m.Name == "get_Item"), + typeof(InternalEntityEntry).GetRuntimeMethods().Single(m => m.Name == "set_Item"), + typeof(InternalEntityEntry).GetRuntimeMethods().Single(m => m.Name == nameof(InternalEntityEntry.HasDefaultValue)), + typeof(SimpleLogger).GetAnyProperty(nameof(SimpleLogger.Filter)).GetMethod, + typeof(SimpleLogger).GetAnyProperty(nameof(SimpleLogger.Sink)).GetMethod, + typeof(SimpleLogger).GetAnyProperty(nameof(SimpleLogger.FormatOptions)).GetMethod) + { + } + private static readonly Type[] _fluentApiTypes = { typeof(ModelBuilder), @@ -88,8 +103,6 @@ protected override bool ShouldHaveNotNullAnnotation(MethodBase method, Type type && !(type == typeof(IEntityTypeConfiguration<>) && method.Name == nameof(IEntityTypeConfiguration.Configure)); - protected override bool ShouldHaveVirtualMethods(Type type) => type != typeof(InternalEntityEntry); - protected override IEnumerable FluentApiTypes => _fluentApiTypes; protected override Dictionary MetadataTypes diff --git a/test/EFCore.Tests/ApiConsistencyTestBase.cs b/test/EFCore.Tests/ApiConsistencyTestBase.cs index 5582d73248d..39ef7bb1174 100644 --- a/test/EFCore.Tests/ApiConsistencyTestBase.cs +++ b/test/EFCore.Tests/ApiConsistencyTestBase.cs @@ -24,10 +24,12 @@ namespace Microsoft.EntityFrameworkCore { public abstract class ApiConsistencyTestBase { + private readonly HashSet _nonVirtual; private readonly Dictionary _mutableMetadataTypes = new Dictionary(); - public ApiConsistencyTestBase() + protected ApiConsistencyTestBase(params MethodInfo[] nonVirtual) { + _nonVirtual = nonVirtual.ToHashSet(); foreach (var typeTuple in MetadataTypes) { _mutableMetadataTypes[typeTuple.Value.Mutable] = typeTuple.Value.Convention; @@ -275,17 +277,15 @@ var nonVirtualMethods = (from type in GetAllTypes(TargetAssembly.GetTypes()) where type.GetTypeInfo().IsVisible && !type.GetTypeInfo().IsSealed - && type.GetConstructors(AnyInstance).Any(c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly) - && type.Namespace?.EndsWith(".Compiled", StringComparison.Ordinal) == false - && ShouldHaveVirtualMethods(type) from method in type.GetMethods(AnyInstance) + let mustBeVirtual = !_nonVirtual.Contains(method) + let isVirtual = method.IsVirtual && !method.IsFinal where method.DeclaringType == type - && !(method.IsVirtual && !method.IsFinal) + && mustBeVirtual != isVirtual && !method.Name.StartsWith("add_", StringComparison.Ordinal) && !method.Name.StartsWith("remove_", StringComparison.Ordinal) && !method.Name.Equals("get_NodeType", StringComparison.Ordinal) && (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly) - && method.Name != "GenerateCacheKeyCore" select type.FullName + "." + method.Name) .ToList(); @@ -294,9 +294,6 @@ from method in type.GetMethods(AnyInstance) "\r\n-- Missing virtual APIs --\r\n" + string.Join(Environment.NewLine, nonVirtualMethods)); } - protected virtual bool ShouldHaveVirtualMethods(Type type) - => true; - [ConditionalFact] public virtual void Public_api_arguments_should_have_not_null_annotation() { diff --git a/test/EFCore.Tests/Infrastructure/DiagnosticsLoggerTest.cs b/test/EFCore.Tests/Infrastructure/DiagnosticsLoggerTest.cs index 948443aaa52..1318763dffb 100644 --- a/test/EFCore.Tests/Infrastructure/DiagnosticsLoggerTest.cs +++ b/test/EFCore.Tests/Infrastructure/DiagnosticsLoggerTest.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.Linq; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.Extensions.Logging; @@ -45,11 +46,11 @@ private void FilterTest(Func filter, params string[] expected) var loggerFactory = new ListLoggerFactory(filter); var dbLogger = new DiagnosticsLogger( - loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestLoggingDefinitions()); + loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestLoggingDefinitions(), new NullSimpleLogger()); var sqlLogger = new DiagnosticsLogger( - loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestLoggingDefinitions()); + loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestLoggingDefinitions(), new NullSimpleLogger()); var queryLogger = new DiagnosticsLogger( - loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestLoggingDefinitions()); + loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestLoggingDefinitions(), new NullSimpleLogger()); var randomLogger = loggerFactory.CreateLogger("Random"); dbLogger.Logger.LogInformation(1, "DB1"); diff --git a/test/EFCore.Tests/Infrastructure/EventIdTestBase.cs b/test/EFCore.Tests/Infrastructure/EventIdTestBase.cs index 012bf286218..f59d9afc92c 100644 --- a/test/EFCore.Tests/Infrastructure/EventIdTestBase.cs +++ b/test/EFCore.Tests/Infrastructure/EventIdTestBase.cs @@ -70,6 +70,7 @@ public void TestEventLogging( var testLogger = (TestLoggerBase)Activator.CreateInstance(typeof(TestLogger<,>).MakeGenericType(category, loggerDefinitionsType)); var testDiagnostics = (TestDiagnosticSource)testLogger.DiagnosticSource; + var simpleLogger = (TestSimpleLogger)testLogger.SimpleLogger; var args = new object[loggerParameters.Length]; args[0] = testLogger; @@ -112,6 +113,12 @@ public void TestEventLogging( { Assert.Equal(logLevel, testLogger.LoggedAt); logged = true; + + if (categoryName != DbLoggerCategory.Scaffolding.Name) + { + Assert.Equal(logLevel, simpleLogger.LoggedAt); + Assert.Equal(eventId, simpleLogger.LoggedEvent); + } } if (enableFor == eventId.Name diff --git a/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs b/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs index e6d8c69d384..41b69ac1222 100644 --- a/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs +++ b/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs @@ -6,6 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema; using System.Diagnostics; using System.Linq; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -220,7 +221,8 @@ protected virtual void VerifyError(string expectedMessage, IMutableModel model) LoggerFactory, options, new DiagnosticListener("Fake"), - TestHelpers.LoggingDefinitions); + TestHelpers.LoggingDefinitions, + new NullSimpleLogger()); } protected DiagnosticsLogger CreateModelLogger(bool sensitiveDataLoggingEnabled = false) @@ -231,7 +233,8 @@ protected virtual void VerifyError(string expectedMessage, IMutableModel model) LoggerFactory, options, new DiagnosticListener("Fake"), - TestHelpers.LoggingDefinitions); + TestHelpers.LoggingDefinitions, + new NullSimpleLogger()); } protected virtual ModelBuilder CreateConventionalModelBuilder(bool sensitiveDataLoggingEnabled = false) diff --git a/test/EFCore.Tests/Metadata/Conventions/ForeignKeyPropertyDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/ForeignKeyPropertyDiscoveryConventionTest.cs index da9fd7cc331..be45684e4a4 100644 --- a/test/EFCore.Tests/Metadata/Conventions/ForeignKeyPropertyDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/ForeignKeyPropertyDiscoveryConventionTest.cs @@ -1154,7 +1154,8 @@ private ProviderConventionSetBuilderDependencies CreateDependencies() ListLoggerFactory, options, new DiagnosticListener("Fake"), - new TestLoggingDefinitions()); + new TestLoggingDefinitions(), + new NullSimpleLogger()); return modelLogger; } diff --git a/test/EFCore.Tests/Metadata/Conventions/KeyDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/KeyDiscoveryConventionTest.cs index 8a68c8445c8..b60180e958c 100644 --- a/test/EFCore.Tests/Metadata/Conventions/KeyDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/KeyDiscoveryConventionTest.cs @@ -169,7 +169,8 @@ private ProviderConventionSetBuilderDependencies CreateDependencies() ListLoggerFactory, options, new DiagnosticListener("Fake"), - new TestLoggingDefinitions()); + new TestLoggingDefinitions(), + new NullSimpleLogger()); return modelLogger; } diff --git a/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs index 7a27ab62c4a..59088aed4ae 100644 --- a/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs @@ -896,7 +896,8 @@ private static ProviderConventionSetBuilderDependencies CreateDependencies(Diagn ListLoggerFactory, options, new DiagnosticListener("Fake"), - new TestLoggingDefinitions()); + new TestLoggingDefinitions(), + new NullSimpleLogger()); return modelLogger; } diff --git a/test/EFCore.Tests/Metadata/Conventions/NonNullableNavigationConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/NonNullableNavigationConventionTest.cs index f457d0e9c59..9d7c451699f 100644 --- a/test/EFCore.Tests/Metadata/Conventions/NonNullableNavigationConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/NonNullableNavigationConventionTest.cs @@ -226,7 +226,8 @@ private ProviderConventionSetBuilderDependencies CreateDependencies() ListLoggerFactory, options, new DiagnosticListener("Fake"), - new TestLoggingDefinitions()); + new TestLoggingDefinitions(), + new NullSimpleLogger()); return modelLogger; } diff --git a/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs index 8b844d51faf..050bfb96162 100644 --- a/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs @@ -991,7 +991,8 @@ private static IMemberClassifier CreateMemberClassifier() ListLoggerFactory, options, new DiagnosticListener("Fake"), - new TestLoggingDefinitions()); + new TestLoggingDefinitions(), + new NullSimpleLogger()); return modelLogger; } diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs index e75fb2c2105..ce92d331226 100644 --- a/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; @@ -122,14 +123,16 @@ protected TestModelBuilder(TestHelpers testHelpers) ValidationLoggerFactory, options, new DiagnosticListener("Fake"), - testHelpers.LoggingDefinitions); + testHelpers.LoggingDefinitions, + new NullSimpleLogger()); ModelLoggerFactory = new ListLoggerFactory(l => l == DbLoggerCategory.Model.Name); var modelLogger = new DiagnosticsLogger( ModelLoggerFactory, options, new DiagnosticListener("Fake"), - testHelpers.LoggingDefinitions); + testHelpers.LoggingDefinitions, + new NullSimpleLogger()); ModelBuilder = testHelpers.CreateConventionBuilder(modelLogger, validationLogger); } diff --git a/test/EFCore.Tests/SimpleLoggerTests.cs b/test/EFCore.Tests/SimpleLoggerTests.cs new file mode 100644 index 00000000000..cfd84fef8ee --- /dev/null +++ b/test/EFCore.Tests/SimpleLoggerTests.cs @@ -0,0 +1,470 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.EntityFrameworkCore +{ + public class SimpleLoggerTests + { + private const string ContextInitialized = + @"info: HH:mm:ss.fff CoreEventId.ContextInitialized[10403] (Microsoft.EntityFrameworkCore.Infrastructure) + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "; + + private const string SaveChangesStarting = + @"dbug: HH:mm:ss.fff CoreEventId.SaveChangesStarting[10004] (Microsoft.EntityFrameworkCore.Update) + SaveChanges starting for 'LoggingContext'."; + + private const string SaveChangesCompleted = + @"dbug: HH:mm:ss.fff CoreEventId.SaveChangesCompleted[10005] (Microsoft.EntityFrameworkCore.Update) + SaveChanges completed for 'LoggingContext' with 0 entities written to the database."; + + private const string ContextDisposed = + @"dbug: HH:mm:ss.fff CoreEventId.ContextDisposed[10407] (Microsoft.EntityFrameworkCore.Infrastructure) + 'LoggingContext' disposed."; + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_with_default_options(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest(async, stream, b => b.LogTo(stream.WriteLine)); + + AssertLog(actual, ContextInitialized, SaveChangesStarting, SaveChangesCompleted, ContextDisposed); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_with_minimum_level(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest(async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information)); + + AssertLog(actual, ContextInitialized); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_multiple_categories(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { DbLoggerCategory.Infrastructure.Name, DbLoggerCategory.Update.Name })); + + AssertLog(actual, ContextInitialized, SaveChangesStarting, SaveChangesCompleted, ContextDisposed); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_single_category(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { DbLoggerCategory.Infrastructure.Name })); + + AssertLog(actual, ContextInitialized, ContextDisposed); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_single_category_and_minimum_level(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { DbLoggerCategory.Infrastructure.Name }, + LogLevel.Information)); + + AssertLog(actual, ContextInitialized); + + stream = new StringWriter(); + actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { DbLoggerCategory.Update.Name }, + LogLevel.Information)); + + Assert.Equal("", actual); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_single_event(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { CoreEventId.ContextInitialized })); + + AssertLog(actual, ContextInitialized); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_multiple_events(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { CoreEventId.ContextInitialized, CoreEventId.ContextDisposed })); + + AssertLog(actual, ContextInitialized, ContextDisposed); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_many_events(bool async) // Hits HashCode usage + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] + { + CoreEventId.ContextInitialized, + CoreEventId.ContextDisposed, + CoreEventId.StartedTracking, + CoreEventId.StateChanged, + CoreEventId.ValueGenerated, + CoreEventId.CascadeDelete + })); + + AssertLog(actual, ContextInitialized, ContextDisposed); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_for_single_event_and_minimum_level(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { CoreEventId.ContextInitialized }, + LogLevel.Information)); + + AssertLog(actual, ContextInitialized); + + stream = new StringWriter(); + actual = await LogTest( + async, + stream, + b => b.LogTo( + stream.WriteLine, + new[] { CoreEventId.ContextDisposed }, + LogLevel.Information)); + + Assert.Equal("", actual); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_with_custom_filter(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, (e, l) => e == CoreEventId.SaveChangesCompleted)); + + AssertLog(actual, SaveChangesCompleted); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_with_custom_logger(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest(async, stream, b => b.LogTo(new CustomSimpleLogger(stream.Write))); + + Assert.Equal(@"Initialized LoggingContext" + Environment.NewLine, actual); + } + + private class CustomSimpleLogger : ISimpleLogger + { + public CustomSimpleLogger([NotNull] Action sink) + { + Sink = sink; + } + + public virtual Action Sink { get; } + + public void Log(EventData eventData) + => Sink("Initialized " + ((ContextInitializedEventData)eventData).Context.GetType().Name); + + public bool ShouldLog(EventId eventId, LogLevel logLevel) + => eventId == CoreEventId.ContextInitialized; + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_with_raw_message(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.None)); + + AssertLog( + actual, + @"Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_raw_single_line(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.SingleLine)); + + AssertLog( + actual, + @"Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_default_single_line(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo( + stream.WriteLine, + LogLevel.Information, + SimpleLoggerFormatOptions.SingleLine | SimpleLoggerFormatOptions.DefaultWithLocalTime)); + + AssertLog( + actual, + @"info: HH:mm:ss.fff CoreEventId.ContextInitialized[10403] (Microsoft.EntityFrameworkCore.Infrastructure) -> Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_only_level(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.Level)); + + AssertLog( + actual, + @"info: + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_only_local_time(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.LocalTime), 0); + + AssertLog( + actual, + @" HH:mm:ss.fff + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_only_UTC_time(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.UtcTime), 0, true); + + AssertLog( + actual, + @"YYYY-MM-DDTHH:MM:SS.MMMMMMTZ + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_only_ID(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.Id)); + + AssertLog( + actual, + @"CoreEventId.ContextInitialized[10403] + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_only_category(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo(stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.Category)); + + AssertLog( + actual, + @"(Microsoft.EntityFrameworkCore.Infrastructure) + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_level_and_ID(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo( + stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.Id | SimpleLoggerFormatOptions.Level)); + + AssertLog( + actual, + @"info: CoreEventId.ContextInitialized[10403] + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_level_and_UTC(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo( + stream.WriteLine, + LogLevel.Information, + SimpleLoggerFormatOptions.UtcTime | SimpleLoggerFormatOptions.Level), + 6, true); + + AssertLog( + actual, + @"info: YYYY-MM-DDTHH:MM:SS.MMMMMMTZ + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public async Task Log_default_UTC(bool async) + { + var stream = new StringWriter(); + var actual = await LogTest( + async, stream, b => b.LogTo( + stream.WriteLine, LogLevel.Information, SimpleLoggerFormatOptions.DefaultWithUtcTime),6, true); + + AssertLog( + actual, + @"info: YYYY-MM-DDTHH:MM:SS.MMMMMMTZ CoreEventId.ContextInitialized[10403] (Microsoft.EntityFrameworkCore.Infrastructure) + Entity Framework Core X.X.X-any initialized 'LoggingContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=SimpleLoggerTests "); + } + + private static void AssertLog(string actual, params string[] lines) + => Assert.Equal( + string.Join(Environment.NewLine, lines) + Environment.NewLine, + actual, + ignoreLineEndingDifferences: true, + ignoreWhiteSpaceDifferences: true); + + private static async Task LogTest( + bool async, + TextWriter writer, + Func, DbContextOptionsBuilder> configureLogging, + int dateAt = 6, + bool utc = false) + { + var options = configureLogging( + new DbContextOptionsBuilder() + .UseInMemoryDatabase("SimpleLoggerTests")) + .Options; + + string productVersion; + + using (var context = new LoggingContext(options)) + { + Assert.Equal(0, async ? await context.SaveChangesAsync() : context.SaveChanges()); + + productVersion = context.Model.GetProductVersion(); + } + + var lines = writer.ToString() + .Replace(productVersion, "X.X.X-any") + .Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); + + var builder = new StringBuilder(); + foreach (var line in lines) + { + var normalized = line; + + if (!normalized.StartsWith("Init", StringComparison.Ordinal)) + { + if (normalized.Contains("20", StringComparison.Ordinal)) + { + var end = (utc ? 28 : 23) + dateAt; + normalized = normalized.Substring(0, dateAt) + + (utc ? "YYYY-MM-DDTHH:MM:SS.MMMMMMTZ" : " HH:mm:ss.fff") + normalized.Substring(end); + } + } + + builder.AppendLine(normalized); + } + + return builder.ToString(); + } + + private class LoggingContext : DbContext + { + public LoggingContext([NotNull] DbContextOptions options) + : base(options) + { + } + } + } +}