Использование Microsoft.Extensions.Logging в EF Core

Microsoft.Extensions.Logging — это расширяемый механизм ведения журнала с поставщиками подключаемых модулей для многих распространенных систем ведения журнала. Подключаемые модули Майкрософт (например , Microsoft.Extensions.Logging.Console) и сторонние подключаемые модули (например , Serilog.Extensions.Logging) доступны в виде пакетов NuGet.

Entity Framework Core (EF Core) полностью интегрируется с Microsoft.Extensions.Logging. Тем не менее, подумайте о использовании простого ведения журнала как более простого способа ведения журналов, особенно для приложений, которые не используют внедрение зависимостей.

Приложения ASP.NET Core

Microsoft.Extensions.Logging используется по умолчанию в приложениях ASP.NET Core. Вызов AddDbContext или AddDbContextPool автоматически делает так, чтобы EF Core использовал конфигурацию логирования, заданную через стандартный механизм ASP.NET.

Другие типы приложений

Другие типы приложений могут использовать GenericHost , чтобы получить те же шаблоны внедрения зависимостей, что и в ASP.NET Core. AddDbContext или AddDbContextPool можно использовать так же, как и в приложениях ASP.NET Core.

Microsoft.Extensions.Logging также можно использовать для приложений, которые не используют внедрение зависимостей, хотя простое ведение журнала может быть проще настроить.

Microsoft.Extensions.Logging требует создания LoggerFactory. Эта фабрика должна храниться как статический или глобальный экземпляр и использоваться каждый раз при создании DbContext. Например, обычно фабрика логгера сохраняется как статическое свойство в DbContext.

public static readonly ILoggerFactory MyLoggerFactory
    = LoggerFactory.Create(builder => { builder.AddConsole(); });

Затем этот одноэлементный или глобальный экземпляр следует зарегистрировать в EF Core на DbContextOptionsBuilder. Рассмотрим пример.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLoggerFactory(MyLoggerFactory)
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");

Получение подробных сообщений

Подсказка

OnConfiguring по-прежнему вызывается при использовании AddDbContext или когда экземпляр DbContextOptions передается конструктору DbContext. Это делает его идеальным местом для применения конфигурации контекста независимо от того, как создается DbContext.

Конфиденциальные данные

По умолчанию EF Core не будет включать значения любых данных в сообщениях об исключениях. Это связано с тем, что такие данные могут быть конфиденциальными и могут быть выявлены в рабочей среде, если исключение не обрабатывается.

Однако знание значений данных, особенно для ключей, может оказаться очень полезным при отладке. Это можно включить в EF Core путем вызова EnableSensitiveDataLogging(). Рассмотрим пример.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.EnableSensitiveDataLogging();

Подробные исключения запросов

По соображениям производительности EF Core не упаковывает каждый вызов для чтения значения от поставщика базы данных в блоке try-catch. Однако иногда это приводит к возникновению исключений, которые трудно диагностировать, особенно если база данных возвращает значение NULL, если это не разрешено моделью.

EnableDetailedErrors Включение приведет к тому, что EF вводит эти блоки try-catch и тем самым предоставляет более подробные ошибки. Рассмотрим пример.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.EnableDetailedErrors();

Конфигурация для определенных сообщений

API EF Core ConfigureWarnings позволяет приложениям изменять то, что происходит при обнаружении определенного события. Это можно использовать для следующих способов:

  • Изменение уровня журнала, на котором регистрируется событие
  • Пропустить полностью регистрацию события
  • Создание исключения при возникновении события

Изменение уровня журнала для события

Иногда это может быть полезно для изменения предварительно определенного уровня журнала для события. Например, это можно использовать для продвижения двух дополнительных событий из LogLevel.Debug в LogLevel.Information.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(
            b => b.Log(
                (RelationalEventId.ConnectionOpened, LogLevel.Information),
                (RelationalEventId.ConnectionClosed, LogLevel.Information)));

Подавление регистрации события

Таким же образом можно отключить отдельное событие из ведения журнала. Это особенно полезно для игнорировать предупреждение, которое было проверено и понято. Рассмотрим пример.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning));

Создание события

Наконец, EF Core можно настроить на выбрасывание исключений для данного события. Это особенно полезно для изменения предупреждения в ошибку. (Действительно, это была исходная цель ConfigureWarnings метода, следовательно, имя.) Например:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Throw(RelationalEventId.QueryPossibleUnintendedUseOfEqualsWarning));

Фильтрация и другая конфигурация

Сведения о фильтрации журналов и другой конфигурации см. в разделе "Ведение журнала в .NET ".

События логирования EF Core определяются одним из:

  • CoreEventId для событий, общих для всех поставщиков баз данных EF Core
  • RelationalEventId для событий, общих для всех поставщиков реляционных баз данных
  • Аналогичный класс для событий, относящихся к текущему поставщику базы данных. Например, SqlServerEventId для поставщика SQL Server.

Эти определения содержат идентификаторы событий, уровень логирования и категорию для каждого события, как используется в контексте Microsoft.Extensions.Logging.