Skip to content

EF Core 记录日志 Logging

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

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

powershell
Install-Package Microsoft.Extensions.Logging.Console

或者用

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

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

在注入Dbcontext的时候配置好 ILoggerFactory

csharp
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;
}

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

csharp
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();

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

shell
 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

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

csharp
// 对 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.BinderMicrosoft.Extensions.Configuration.Json

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

csharp
 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

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命令把代码签出到本地

powershell
git clone https://gitee.com/malema/Examples
git checkout EFCore/logging_configuration

简单就是美