Skip to content

Commit

Permalink
Standardize and consolidate logging
Browse files Browse the repository at this point in the history
Issues #7217 #218

This change:
* Consolidates interception and sensitive logging into one service and uses that service everywhere in the EF code.
* Adds a LoggerCategory class which contains nested classes that define EF logging categories.
* Used together, this means any EF service can depend on `IInterceptingLogger<TLoggingCategory>` and have D.I. fill create the correct service using its open generics feature. The TLoggingCategory is constrained so that only types specifically defined as LoggingCategories can be used. For example, `IInterceptingLogger<LoggingCategory.Database.Sql>`.
* Application code can get logging categories using, for example, `LoggingCategory.Database.Sql.Name`. This means that any application can immediately see in code what logging categories there are to do appropriate filtering.
* All services depend on the specific generic `IInterceptingLogger<TLoggingCategory>` that they will use--never ILogger. This makes it very clear which category is being logged to and makes it safe to share loggers where safe, and impossible where the categories should be different.
  • Loading branch information
ajcvickers committed Apr 12, 2017
1 parent f274b88 commit 3b7459c
Show file tree
Hide file tree
Showing 84 changed files with 704 additions and 534 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ protected virtual IServiceCollection ConfigureContextServices(
[NotNull] IServiceCollection services)
=> services
.AddTransient<MigrationsScaffolder>()
.AddTransient(_ => contextServices.GetService<ILoggingOptions>())
.AddTransient(_ => contextServices.GetService(typeof(IInterceptingLogger<>)))
.AddTransient(_ => contextServices.GetService<ICurrentDbContext>())
.AddTransient(_ => contextServices.GetService<IDatabaseProvider>())
.AddTransient(_ => contextServices.GetService<IDbContextOptions>())
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore.InMemory/Storage/Internal/IInMemoryStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.Extensions.Logging;

namespace Microsoft.EntityFrameworkCore.Storage.Internal
{
Expand Down Expand Up @@ -37,6 +37,6 @@ public interface IInMemoryStore
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
int ExecuteTransaction([NotNull] IEnumerable<IUpdateEntry> entries, [NotNull] ILogger<InMemoryDatabase> logger);
int ExecuteTransaction([NotNull] IEnumerable<IUpdateEntry> entries, [NotNull] IInterceptingLogger<LoggerCategory.Update> updateLogger);
}
}
13 changes: 6 additions & 7 deletions src/EFCore.InMemory/Storage/Internal/InMemoryDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.Logging;
using Remotion.Linq;

namespace Microsoft.EntityFrameworkCore.Storage.Internal
Expand All @@ -24,7 +23,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.Internal
public class InMemoryDatabase : Database, IInMemoryDatabase
{
private readonly IInMemoryStore _store;
private readonly ILogger<InMemoryDatabase> _logger;
private readonly IInterceptingLogger<LoggerCategory.Update> _updateLogger;

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
Expand All @@ -34,15 +33,15 @@ public InMemoryDatabase(
[NotNull] DatabaseDependencies dependencies,
[NotNull] IInMemoryStoreSource storeSource,
[NotNull] IDbContextOptions options,
[NotNull] ILogger<InMemoryDatabase> logger)
[NotNull] IInterceptingLogger<LoggerCategory.Update> updateLogger)
: base(dependencies)
{
Check.NotNull(storeSource, nameof(storeSource));
Check.NotNull(options, nameof(options));
Check.NotNull(logger, nameof(logger));
Check.NotNull(updateLogger, nameof(updateLogger));

_store = storeSource.GetStore(options);
_logger = logger;
_updateLogger = updateLogger;
}

/// <summary>
Expand All @@ -56,7 +55,7 @@ public InMemoryDatabase(
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public override int SaveChanges(IReadOnlyList<IUpdateEntry> entries)
=> _store.ExecuteTransaction(Check.NotNull(entries, nameof(entries)), _logger);
=> _store.ExecuteTransaction(Check.NotNull(entries, nameof(entries)), _updateLogger);

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
Expand All @@ -65,7 +64,7 @@ public override int SaveChanges(IReadOnlyList<IUpdateEntry> entries)
public override Task<int> SaveChangesAsync(
IReadOnlyList<IUpdateEntry> entries,
CancellationToken cancellationToken = default(CancellationToken))
=> Task.FromResult(_store.ExecuteTransaction(Check.NotNull(entries, nameof(entries)), _logger));
=> Task.FromResult(_store.ExecuteTransaction(Check.NotNull(entries, nameof(entries)), _updateLogger));

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
Expand Down
7 changes: 4 additions & 3 deletions src/EFCore.InMemory/Storage/Internal/InMemoryStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.Extensions.Logging;

namespace Microsoft.EntityFrameworkCore.Storage.Internal
{
Expand Down Expand Up @@ -104,7 +103,9 @@ public virtual IReadOnlyList<InMemoryTableSnapshot> GetTables(IEntityType entity
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public virtual int ExecuteTransaction(IEnumerable<IUpdateEntry> entries, ILogger<InMemoryDatabase> logger)
public virtual int ExecuteTransaction(
IEnumerable<IUpdateEntry> entries,
IInterceptingLogger<LoggerCategory.Update> updateLogger)
{
var rowsAffected = 0;

Expand Down Expand Up @@ -139,7 +140,7 @@ public virtual int ExecuteTransaction(IEnumerable<IUpdateEntry> entries, ILogger
}
}

logger.LogInformation<object>(
updateLogger.LogInformation<object>(
InMemoryEventId.SavedChanges,
rowsAffected,
InMemoryStrings.LogSavedChanges);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.Logging;

namespace Microsoft.EntityFrameworkCore.Storage.Internal
{
public class InMemoryTransactionManager : IDbContextTransactionManager
{
private static readonly InMemoryTransaction _stubTransaction = new InMemoryTransaction();

private readonly ILogger<InMemoryTransactionManager> _logger;
private readonly IInterceptingLogger<LoggerCategory.Database.Transaction> _logger;

public InMemoryTransactionManager(
[NotNull] ILogger<InMemoryTransactionManager> logger)
[NotNull] IInterceptingLogger<LoggerCategory.Database.Transaction> logger)
{
Check.NotNull(logger, nameof(logger));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Relational.Design.Specification.Tests.TestUtilities;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
Expand All @@ -30,7 +32,10 @@ protected E2ETestBase(ITestOutputHelper output)

var serviceBuilder = new ServiceCollection()
.AddScaffolding()
.AddLogging();
.AddLogging()
.AddSingleton<ILoggingOptions, LoggingOptions>()
.AddSingleton(typeof(IInterceptingLogger<>), typeof(InterceptingLogger<>));

ConfigureDesignTimeServices(serviceBuilder);

var serviceProvider = serviceBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore.Extensions;

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
Expand All @@ -27,7 +25,7 @@ public class RelationalScaffoldingModelFactory : IScaffoldingModelFactory
internal const string NavigationNameUniquifyingPattern = "{0}Navigation";
internal const string SelfReferencingPrincipalEndNavigationNamePattern = "Inverse{0}";

protected virtual ILogger Logger { get; }
protected virtual IInterceptingLogger<LoggerCategory.Scaffolding> Logger { get; }
protected virtual IRelationalTypeMapper TypeMapper { get; }
protected virtual CandidateNamingService CandidateNamingService { get; }

Expand All @@ -39,19 +37,19 @@ public class RelationalScaffoldingModelFactory : IScaffoldingModelFactory
private readonly IPluralizer _pluralizer;

public RelationalScaffoldingModelFactory(
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IInterceptingLogger<LoggerCategory.Scaffolding> logger,
[NotNull] IRelationalTypeMapper typeMapper,
[NotNull] IDatabaseModelFactory databaseModelFactory,
[NotNull] CandidateNamingService candidateNamingService,
[NotNull] IPluralizer pluralizer)
{
Check.NotNull(loggerFactory, nameof(loggerFactory));
Check.NotNull(logger, nameof(logger));
Check.NotNull(typeMapper, nameof(typeMapper));
Check.NotNull(databaseModelFactory, nameof(databaseModelFactory));
Check.NotNull(candidateNamingService, nameof(candidateNamingService));
Check.NotNull(pluralizer, nameof(pluralizer));

Logger = loggerFactory.CreateLogger<RelationalScaffoldingModelFactory>();
Logger = logger;
TypeMapper = typeMapper;
CandidateNamingService = candidateNamingService;
_databaseModelFactory = databaseModelFactory;
Expand Down
5 changes: 2 additions & 3 deletions src/EFCore.Relational/Migrations/Internal/Migrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.Logging;

namespace Microsoft.EntityFrameworkCore.Migrations.Internal
{
Expand All @@ -31,7 +30,7 @@ public class Migrator : IMigrator
private readonly IMigrationCommandExecutor _migrationCommandExecutor;
private readonly IRelationalConnection _connection;
private readonly ISqlGenerationHelper _sqlGenerationHelper;
private readonly ILogger _logger;
private readonly IInterceptingLogger<LoggerCategory.Migrations> _logger;
private readonly string _activeProvider;

/// <summary>
Expand All @@ -47,7 +46,7 @@ public Migrator(
[NotNull] IMigrationCommandExecutor migrationCommandExecutor,
[NotNull] IRelationalConnection connection,
[NotNull] ISqlGenerationHelper sqlGenerationHelper,
[NotNull] ILogger<Migrator> logger,
[NotNull] IInterceptingLogger<LoggerCategory.Migrations> logger,
[NotNull] IDatabaseProvider databaseProvider)
{
Check.NotNull(migrationsAssembly, nameof(migrationsAssembly));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.Logging;

namespace Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.Internal
{
Expand All @@ -18,13 +17,13 @@ namespace Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.Internal
/// </summary>
public class EqualsTranslator : IMethodCallTranslator
{
private readonly ILogger _logger;
private readonly IInterceptingLogger<LoggerCategory.Query> _logger;

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public EqualsTranslator([NotNull] ILogger logger)
public EqualsTranslator([NotNull] IInterceptingLogger<LoggerCategory.Query> logger)
{
Check.NotNull(logger, nameof(logger));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace Microsoft.EntityFrameworkCore.Query.ExpressionTranslators
{
Expand Down Expand Up @@ -39,22 +39,22 @@ public sealed class RelationalCompositeMethodCallTranslatorDependencies
/// </para>
/// </summary>
/// <param name="logger"> A logger. </param>
public RelationalCompositeMethodCallTranslatorDependencies([NotNull] ILogger<IMethodCallTranslator> logger)
public RelationalCompositeMethodCallTranslatorDependencies([NotNull] IInterceptingLogger<LoggerCategory.Query> logger)
{
Logger = logger;
}

/// <summary>
/// The logger.
/// </summary>
public ILogger<IMethodCallTranslator> Logger { get; }
public IInterceptingLogger<LoggerCategory.Query> Logger { get; }

/// <summary>
/// Clones this dependency parameter object with one service replaced.
/// </summary>
/// <param name="logger"> A replacement for the current dependency of this type. </param>
/// <returns> A new parameter object with the given service replaced. </returns>
public RelationalCompositeMethodCallTranslatorDependencies With([NotNull] ILogger<IMethodCallTranslator> logger)
public RelationalCompositeMethodCallTranslatorDependencies With([NotNull] IInterceptingLogger<LoggerCategory.Query> logger)
=> new RelationalCompositeMethodCallTranslatorDependencies(logger);
}
}
4 changes: 2 additions & 2 deletions src/EFCore.Relational/Storage/Internal/RelationalCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class RelationalCommand : IRelationalCommand
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public RelationalCommand(
[NotNull] ISensitiveDataLogger logger,
[NotNull] IInterceptingLogger<LoggerCategory.Database.Sql> logger,
[NotNull] DiagnosticSource diagnosticSource,
[NotNull] string commandText,
[NotNull] IReadOnlyList<IRelationalParameter> parameters)
Expand All @@ -45,7 +45,7 @@ public RelationalCommand(
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
protected virtual ISensitiveDataLogger Logger { get; }
protected virtual IInterceptingLogger<LoggerCategory.Database.Sql> Logger { get; }

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.Internal
/// </summary>
public class RelationalCommandBuilder : IRelationalCommandBuilder
{
private readonly ISensitiveDataLogger _logger;
private readonly IInterceptingLogger<LoggerCategory.Database.Sql> _logger;
private readonly DiagnosticSource _diagnosticSource;

private readonly IndentedStringBuilder _commandTextBuilder = new IndentedStringBuilder();
Expand All @@ -26,7 +26,7 @@ public class RelationalCommandBuilder : IRelationalCommandBuilder
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public RelationalCommandBuilder(
[NotNull] ISensitiveDataLogger logger,
[NotNull] IInterceptingLogger<LoggerCategory.Database.Sql> logger,
[NotNull] DiagnosticSource diagnosticSource,
[NotNull] IRelationalTypeMapper typeMapper)
{
Expand Down Expand Up @@ -64,12 +64,12 @@ public virtual IRelationalCommand Build()
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
protected virtual IRelationalCommand BuildCore(
[NotNull] ISensitiveDataLogger sensitiveDataLogger,
[NotNull] IInterceptingLogger<LoggerCategory.Database.Sql> logger,
[NotNull] DiagnosticSource diagnosticSource,
[NotNull] string commandText,
[NotNull] IReadOnlyList<IRelationalParameter> parameters)
=> new RelationalCommand(
sensitiveDataLogger, diagnosticSource, commandText, parameters);
logger, diagnosticSource, commandText, parameters);

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.Internal
/// </summary>
public class RelationalCommandBuilderFactory : IRelationalCommandBuilderFactory
{
private readonly ISensitiveDataLogger _logger;
private readonly IInterceptingLogger<LoggerCategory.Database.Sql> _logger;
private readonly DiagnosticSource _diagnosticSource;
private readonly IRelationalTypeMapper _typeMapper;

Expand All @@ -23,7 +23,7 @@ public class RelationalCommandBuilderFactory : IRelationalCommandBuilderFactory
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public RelationalCommandBuilderFactory(
[NotNull] ISensitiveDataLogger<IRelationalCommandBuilderFactory> logger,
[NotNull] IInterceptingLogger<LoggerCategory.Database.Sql> logger,
[NotNull] DiagnosticSource diagnosticSource,
[NotNull] IRelationalTypeMapper typeMapper)
{
Expand All @@ -47,11 +47,11 @@ public RelationalCommandBuilderFactory(
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
protected virtual IRelationalCommandBuilder CreateCore(
[NotNull] ISensitiveDataLogger sensitiveDataLogger,
[NotNull] IInterceptingLogger<LoggerCategory.Database.Sql> logger,
[NotNull] DiagnosticSource diagnosticSource,
[NotNull] IRelationalTypeMapper relationalTypeMapper)
=> new RelationalCommandBuilder(
sensitiveDataLogger,
logger,
diagnosticSource,
relationalTypeMapper);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static class RelationalLoggerExtensions
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public static void LogCommandExecuted(
[NotNull] this ISensitiveDataLogger logger,
[NotNull] this IInterceptingLogger<LoggerCategory.Database.Sql> logger,
[NotNull] DbCommand command,
long startTimestamp,
long currentTimestamp)
Expand Down
Loading

0 comments on commit 3b7459c

Please sign in to comment.