【Entity Framework】EF日志-简单日志记录
文章目录
- 【Entity Framework】EF日志-简单日志记录
- 一、概述
- 二、EF日志分类
- 三、简单的日志记录
- 3.1 配置
- 3.2 日志记录到控制台
- 3.3 记录到凋试窗口
- 3.4 记录到文件
- 3.5 敏感数据处理
- 3.6 详细查询异常
- 3.6 日志级别
- 3.7 消息内容和格式设置
一、概述
Entity Framework Core (EF Core)包含一些用于生成日志,响应事件和获取诊断结果的机制。其中每种机制都针对不同情况进行了定制,务必针对手头上的任务选择最佳机制,即使是多个机制都适用也是如此。本文将介绍EF日志每种机制,及其描述每种机制应用场景。
二、EF日志分类
下表提供了有关此处所述机制之间的差异的快速参考。
序列 | 机制 | Async | 范围 | 已注册 | 预期用途 |
---|---|---|---|---|---|
1 | 简单的日志记录 | 否 | 按上下文 | 上下文配置 | 开发时日志记录 |
2 | Microsoft.Extension.Logging | 否 | 按上下文 | D.I或上下文配置 | 生产日志记录 |
3 | 事件 | 否 | 按上下文 | 任何时间 | 对 EF 事件做出反应 |
4 | 拦截器 | 是 | 按上下文 | 上下文配置 | 进行 EF 操作 |
5 | 诊断侦听器 | 否 | 进程 | 全局 | 应用程序诊断 |
Microsoft.Extensions.Logging通常通过依赖项注入在每个应用程序中进行配置。但在EF级别,可使用不同的记录器配置没个上下文。
三、简单的日志记录
Entity Framework Core
简单日志记录可用于在开发和调试应用程序时轻松获取日志。这种形式的日志记录只需进行极少的配置,不需要额外的NuGet
包。
3.1 配置
可以在配置DbContext实例时使用LogTo
从任意类型的应用程序访问EF Core日志。此配置通常通过替代DbContext.OnConfiguring
来完成。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.LogTo(Console.WriteLine);
或者,可将LogTo
作为AddDbContext
的一部分来调用,或者在创建DbContextOptions
实例以传递给DbContext
构造函数时进行调用。
当使用 AddDbContext 或将 DbContextOptions 实例传递给 DbContext 构造函数时,仍会调用 OnConfiguring。 这使得它成为应用上下文配置的理想位置,而无需考虑如何构造 DbContext。
3.2 日志记录到控制台
LogTo
需要一个接受字符串Action<T>
委托。EF Core将使用字符串为生成的每条日志消息调用此委托。然后由该委托对给定消息执行某些操作。
此委托通常使用Console.WriteLine
方式,如上所示。这导致每条日志消息都被写入控制台。
3.3 记录到凋试窗口
Debug.WriteLine
可用于将输出发送到Visual Studio
或其他IDE中凋试窗口。在这种情况下必须使用Lambda
语法,因此Debug
类是从发布版本编译的。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.LogTo(message => Debug.WriteLine(message));
3.4 记录到文件
写入文件时,需要为文件创建SteamWriter
或相似的类。然后可以像上面的其他示例一样使用WriteLine
方法。请记住,通过在释放上下文时是否编写器来确保文件完全关闭。示例:
private readonly StreamWriter _logStream=new StreamWriter("mylog.txt",append:true);
protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder)
{
optionBuilder.LogTo(_logStream.WriteLine);
}
public override void Dispose()
{
base.Dispose();
_logStream.Dispose();
}
public override async ValueTask DisposeAsync()
{
await base.DisposeAsync();
await _logStream.DisposeAsync();
}
3.5 敏感数据处理
默认情况下,EF Core不会在异常消息中包含任何数据的值。这是因为这些数据可能是机密数据,如果不处理异常,可能会在生产使用中泄露这些数据。
但是,了解数据值(尤其是键值)在凋试时非常有用。可以通过调用EnableSensitiveDataLogging()
在EF Core中启用此功能。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.LogTo(Console.WriteLine)
.EnableSensitiveDataLogging();
}
3.6 详细查询异常
出于性能原因,EF Core不会在try-catch块中包装每个调用以数据库提供程序读取值。但是,这有时会导致难以诊断的异常,尤其是当数据库在模型下允许的情况下返回NULL时。
启用EnableDetailedErrors
将导致EF引入这些try-catch块,从而提供更详细的错误。例如:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.LogTo(Console.WriteLine).EnableDetailedErrors();
}
3.6 日志级别
系统会为每条EF Core
日志消息分配由LogLevel
枚举定义的级别。默认情况下,EF Core简单日志记录包括Debug
级别或高级版的每条消息。LogTo
可以传递一个更高的最低级别来筛选掉某些消息。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);
3.7 消息内容和格式设置
LogTo
中的默认内容跨多行设置格式。 第一行包含消息元数据:
LogLevel
作为四字符前缀- 本地时间戳,针对当前域性设置格式
EventId
,采用可以复制/粘贴以从CoreEventId
或其他EventId
类之一获取成员的格式,外加原始ID值。- 事件类别