EF Core 记录日志 Logging

EF Core 使用的日志系统也是 Microsoft.Extensions.Logging

首先让我们添加一个Console Provider 包是这个 Microsoft.Extensions.Logging.Console

Install-Package Microsoft.Extensions.Logging.Console

或者用

dotnet add ./ConsoleApp/ConsoleApp.csproj package Microsoft.Extensions.Logging.Console

如果是Asp.net core 项目我们就不需要管这些了。因为这些东西已经全部加好了。

在注入Dbcontext的时候配置好 ILoggerFactory

private static ServiceProvider GetSserviceProvider()
{
    var connectionString = "Data Source=127.0.0.1;Initial Catalog=MalemaEFCoreExampleU1;Persist Security Info=True;User Id=sa;Password=malema987%^&";
    var optionBuilder = new DbContextOptionsBuilder<MalemaDbContext>();
    optionBuilder.UseSqlServer(connectionString);
    var services = new ServiceCollection();
    //services.AddDbContext<MalemaDbContext>(options => options.UseSqlServer(connectionString));
    //services.AddDbContextFactory<MalemaDbContext>(options => options.UseSqlServer(connectionString));
    services.AddLogging(x => x.AddConsole()); //注入Logging
    services.AddDbContextPool<MalemaDbContext>((sp, options) =>
    {
        options.UseLoggerFactory(sp.GetRequiredService<ILoggerFactory>()) //注入IloggerFactory
        .UseSqlServer(connectionString);

    }, poolSize: 64);
    services.AddPooledDbContextFactory<MalemaDbContext>((sp, options) =>
    {
        options.UseLoggerFactory(sp.GetRequiredService<ILoggerFactory>())
        .UseSqlServer(connectionString);
    }, poolSize: 64);
    services.AddScoped<StudentService, StudentService>();
    var sp = services.BuildServiceProvider();
    return sp;
}

当我们用下面的方法更新数据库时

var malemaDbContext = sp.GetService<MalemaDbContext>();
var student = new Student() { Name = "abcaaaqqqq", Age = 1 };
var k = malemaDbContext.Update(student);
malemaDbContext.SaveChanges();

var mlmDbContext2 = sp.GetService<MalemaDbContext>();
var student2 = mlmDbContext2.Find<Student>(1);
mlmDbContext2.Update(student2);//update是更新了所有的属性。而不管这个类是不是从dbContext里面查出来的
mlmDbContext2.SaveChanges();

我们会看到如下的日志记录

 SELECT 1 ELSE SELECT 0
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (14ms) [Parameters=[@p0='1', @p1='abcaaaqqqq' (Size = 50)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      INSERT INTO [Students] ([Age], [Name])
      VALUES (@p0, @p1);
      SELECT [Id]
      FROM [Students]
      WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[@__p_0='1'], CommandType='Text', CommandTimeout='30']
      SELECT TOP(1) [s].[Id], [s].[Age], [s].[Name]
      FROM [Students] AS [s]
      WHERE [s].[Id] = @__p_0
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (2ms) [Parameters=[@p2='1', @p0='1', @p1='abcaaaqqqq' (Size = 50)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      UPDATE [Students] SET [Age] = @p0, [Name] = @p1
      WHERE [Id] = @p2;
      SELECT @@ROWCOUNT;

完整的代码在 logging/step_1下面

进行日志过滤 Logging filter

有时候我们不希望看到一些特殊的日志。我们就可以通过下面的方法来过滤。

// 对 console provider进行过滤
services.AddLogging(x => x.AddConsole().AddFilter((category, level) =>
{
    return category == DbLoggerCategory.Infrastructure.Name && level >= LogLevel.Information;
}));
//整个Logging 也是可以添加过滤的

完整的代码在 logging/step_2下面

分类有下面的这些 (在使用的时候需要加上 DbLoggerCategory.)

  1. Infrastructure
  2. Database.Command
  3. Database.Connection
  4. Database.Transaction
  5. Migration
  6. Model
  7. Query
  8. Scaffolding
  9. Update

启用配置文件 using configuration file

当然我们也可以完全通过配置的方式来进行过滤 首先我们需要添加两个新的包 Microsoft.Extensions.Configuration.Binder Microsoft.Extensions.Configuration.Json

然后我们就可以更改Logging注入的代码

 var configuration = new ConfigurationBuilder()
            .SetBasePath(AppContext.BaseDirectory)
               .AddJsonFile("appsettings.json", true) 
               //在这边我们省略了其它的provider 正常还会加入  .AddEnvironmentVariables()
               .Build();

            services.AddLogging(x =>
            {
                x.AddConfiguration(configuration.GetSection("Logging"))
                .AddConsole();
             });

接下来我们还需要添加一个文件 appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",  //整个 Logging的级别
      //"Microsoft.EntityFrameworkCore.Infrastructure": "Critical", // category的级别
      //"Microsoft.EntityFrameworkCore 所有名称以这个开头的都受控于它
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "Console": { // console provider的级别,会对上面的进行覆盖
      "LogLevel": {
        "Default": "Information",
          //"Microsoft.EntityFrameworkCore.Infrastructure": "Critical", // category的级别
      }
    }
  }
}

完整的代码在 EFCore/logging_configuration下面

可以用下面的git命令把代码签出到本地

git clone https://gitee.com/malema/Examples
git checkout EFCore/logging_configuration
最近更新的
...