ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

asp.net core 3.1 日志记录 Logging

2020-11-24 23:34:42  阅读:402  来源: 互联网

标签:core asp Logging LogLevel ILogger logging 日志 public logger


Ilogger:包括实际执行记录日志操作的方法。
IloggerProvider:用于创建 ILogger 对象。
IloggerFactory:通过 ILoggerProvider 对象创建 ILogger 对象。

ILogger接口

要记录日志,需要使用 ILogger 接口

public interface ILogger
{
	//开始逻辑操作范围。
	IDisposable BeginScope<TState>(TState state);
	//检查是否已启用给定 logLevel。
	bool IsEnabled(LogLevel logLevel);
	//写入日志项。
	void Log<TState> (Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId 		eventId, TState state, Exception exception, Func<TState,Exception,string> formatter);
}

日志级别

Log 方法的第一个参数指明了这条信息的级别,日志级别即其重要程度。ASP.NET Core 日志系统定义了 6 个级别

LogLevel “值” 方法 描述
Trace 0 LogTrace 包含最详细的消息。 这些消息可能包含敏感的应用数据。 这些消息默认情况下处于禁用状态,并且不应在生产中启用。
调试 1 LogDebug 用于调试和开发。 由于量大,请在生产中小心使用。
信息 2 LogInformation 跟踪应用的常规流。 可能具有长期值。
警告 3 LogWarning 对于异常事件或意外事件。 通常包括不会导致应用失败的错误或情况。
错误 4 LogError 表示无法处理的错误和异常。 这些消息表示当前操作或请求失败,而不是整个应用失败。
严重 5 LogCritical 需要立即关注的失败。 例如数据丢失、磁盘空间不足。
6 指定日志记录类别不应写入任何消息。

​ 除了指定日志级别以外,还需要指定 EventId、一个返回值类型为字符串的委托,该委托的意义在于根据指定的状态以及异常返回要输出的日志信息。从上面的代码中可以看出,直接使用 Log 方法来记录日志会非常麻烦。为此 ILogger 接口提供了若干个扩展方法,用来更方便地记录指定级别的日志,它们包括 LogTrace、LogDebug、LogInformation、LogWarning、LogError 和 LogCritical,这几个方法分别对应上面所提到的各个级别。因此,上面的代码可以改写为:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }
    
    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

在Startup记录日志

​ 当 ASP.NET Core 应用程序运行时,日志组件会被添加到其依赖注入容器中,因此只要在合适的位置将 ILogger 对象注入进来,即可使用它来记录日志。

public class Startup
{
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
    {
                app.Run(async (context) =>
                {
                    logger.LogInformation("这是一条测试日志");
                    await context.Response.WriteAsync("Hello, world");
                });
    }
}

在 Startup 类的 Configure 方法中,通过方法注入将ILogger<Startup> 作为该方法的参数注入进来

​ ILogger 接口有一个派生接口 ILogger<out TCategoryName>,其中泛型类型 TCategoryName 表示日志类别名称,它可以是任何类型,通常情况下,它的值应为当前所在类,如上面的 Startup 类。当注入 ILogger 时,必须为其指定泛型类型。

日志事件 ID

​ 在日志的输出结果中,日志类别后有一个用中括号括起来的数字,该数字为事件标识符(Event Id) ,它的值是一个数字,默认值为 0。合理地使用这个数字能够帮助开发者对日志进一步分类,比如,某种操作的 Id 是1000,另一类操作的 Id 是 1002。注意,Event Id 的显示格式由 Provider定义,上述显示形式是由 ConsoleProvider(即控制台日志提供程序)定义的;在其他 Provider 中则不然,例如,DebugProvider 不显示 Event Id。要设置 Event Id,我们只要使用 LogInformation 方法的另一个重载形式即可。

每个日志都可指定一个事件 ID 。 示例应用使用 MyLogEvents 类来定义事件 ID:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

​ 事件 ID 与一组事件相关联。 例如,与在页面上显示项列表相关的所有日志可能是 1001。

​ 日志记录提供程序可将事件 ID 存储在 ID 字段中,存储在日志记录消息中,或者不进行存储。 调试提供程序不显示事件 ID。 控制台提供程序在类别后的括号中显示事件 ID:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

一些日志记录提供程序将事件 ID 存储在一个字段中,该字段允许对 ID 进行筛选。

内置日志记录提供程序

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
	var builder = new WebHostBuilder();
	…
    builder.ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
        logging.AddEventSourceLogger();
    })
	…
}

​ CreateDefaultBuilder 方法默认添加了 3 个日志提供程序,如果不需要默认所添加的这些日志提供程序,可以调用 ILoggerProvider 接口的 ClearProviders 方法,然后再添加所需要的日志提供程序。

  • 控制台
    向控制台窗口输出日志
  • 调试
    向开发环境(IDE)的调试窗口输出日志,它会调用System.Diagnostics.Debug 类的 WriteLine 方法向外输出。
  • EventSource
    向事件跟踪器输出日志。
  • EventLog
    向 Window Event Log 输出日志,仅支持 Windows 操作系统。
  • AzureAppServicesFile 和 AzureAppServicesBlob
    仅在 Azure 中使用,当应用程序部署到 Azure Web服务中后, Azure App Service 日志提供程序自动会添加进来。
  • ApplicationInsights
    提供程序包将日志写入 Azure Application Insights。 Application Insights 是一项服务,可监视 Web 应用并提供用于查询和分析遥测数据的工具。 如果使用此提供程序,则可以使用 Application Insights 工具来查询和分析日志。

​ 与 ILoggingBuilder 一样,ILoggerFactory 在添加 ASP.NET Core 内置的日志提供程序时,也可以使用 AddConsole 和 AddDebug 等扩展方法来添加日志提供程序。

第三方日志记录提供程序

适用于 ASP.NET Core 的第三方日志记录框架:

某些第三方框架可以执行语义日志记录(又称结构化日志记录)

使用第三方框架类似于使用以下内置提供程序之一:

  1. 将 NuGet 包添加到你的项目。
  2. 调用日志记录框架提供的 ILoggerFactory 扩展方法。

有关详细信息,请参阅各提供程序的相关文档。 Microsoft 不支持第三方日志记录提供程序。

ILoggerFactory

ILoggerFactory 接口用于创建 ILogger 类型的对象。

public interface ILoggerFactory : IDisposable
{
    //将 ILoggerProvider 添加到日志记录系统。
	void AddProvider(ILoggerProvider provider);
	//创建一个新的 ILogger 实例。该方法的参数 categoryName 为类日志的类别名称,它主要用来为日志指定分类名称
	ILogger CreateLogger(string categoryName);
}

要显式指定类别,请调用 ILoggerFactory.CreateLogger

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }
}

分组和过滤

分组

参考:日志作用域

​ 对于一组逻辑上相关的操作,将其日志信息分为一组是很有意义的,这需要使用 Scope 来实现。ILogger 接口有一个方法即BeginScope<TState>(TState state)用于创建 Scope,其中 TState 指明要创建 Scope 的标识符,它可以为任何类型的数据,一般情况下,使用字符串来指明。BeginScope<TState> 方法的返回值类型为 IDisposable,因此可以使用 using 语句块来创建 Scope,代码如下所示。

using (logger.BeginScope("获取数据"))
{
    logger.LogInformation("准备获取数据");
    …
    if (data == null)
    {
    logger.LogError("数据不存在");
    }
}

​ 要在 Scope 中输出日志,除了需要创建 Scope 外,还要在ILoggerProvider 对象中启用这一功能。在添加日志提供程序时可以指定该ILoggerProvider 的一些选项。

​ 例如,对于 ControlProvider,只要设置ConsoleLoggerOptions 的 IncludeScopes 属性为 true,即可为其启用Scope 功能,它的默认值为 false。

1.下列代码为控制台提供程序启用作用域:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.ClearProviders();
                //ConsoleLoggerOptions的 IncludeScopes = true
                logging.AddConsole(options => options.IncludeScopes = true); 
                logging.AddDebug();
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

2.【推荐】以下 JSON 为控制台提供程序启用范围:

{
  "Logging": {
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "IncludeScopes": true, // Required to use Scopes.
      "LogLevel": {
        "Microsoft": "Warning",
        "Default": "Information"
      }
    },
    "LogLevel": {
      "Default": "Debug"
    }
  }
}

输出

info: LoggingTest.Startup[0]
        => 获取数据
        准备获取数据
fail: LoggingTest.Startup[0]
        => 获取数据
        数据不存在

过滤

​ 可以通过设置最低日志级别来进行日志过滤,当这样设置后,所有低于指定日志级别的日志都不会被处理,也不会显示。例如,如果设置最低日志级别为 LogLevel.Information,那么 Debug 和 Trace 级别的日志都不会显示。

1.SetMinimumLevel

​ 要设置最低日志级别,同样需要在 ConfigureLogging 方法中进行配置,此时只要调用 ILoggingBuilder 接口的 SetMinimumLevel 方法即可。

Host.CreateDefaultBuilder(args)
.ConfigureLogging(builder =>
{
builder.ClearProviders();
builder.AddConsole(loggerOptions => loggerOptions.IncludeScopes = true);
builder.SetMinimumLevel(LogLevel.Information);
})
.UseStartup<Startup>();

LogLevel.None

​ 除了之前提到的那些级别以外,还有一个值是 None,该值高于其他所有值。如果指定这个值为最低级别,那么所有的日志都不会输出。

2.AddFilter

​ 除了设置最低日志级别外,ILoggerBuilder 接口还提供了 AddFilter 方法,该方法包括多个重载,它能够指定更复杂的条件,并只显示满足条件的日志。在以下方法中,将显示 LoggeringTest.Startup 类别中,等于并高于Information 级别的日志。

Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
    logging.AddConsole().AddFilter("LoggingTest.Startup", LogLevel.Information);
})

加载JSON的Logging配置

​ 默认情况下,在 appsettings.json 文件中包含了对日志的配置信息,要将日志配置加载并应用到程序的日志系统中,可以调用AddConfiguration 方法

Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
...
})
.UseStartup<Startup>();

​ 在 appsettings.json 配置文件的「Logging」一节则默认包含了关于记录日志的统一配置,如 LogLevel 配置项用于设置对指定类别的日志的最低输出级别,凡是在该类别中低于指定级别的日志将不会被输出。除了设置统一配置外,还可以为每一种日志提供程序提供具体的输出配置,只要在「Logging」一节为其增加相应的配置即可,如下例添加了对 Console 类型日志提供程序的配置。

{
    "Logging": {
            "Console": {
                "IncludeScopes": true,
                "LogLevel": {
                "Microsoft.AspNetCore.Mvc.Razor": "Error",
                "Default": "Information"
                }
            },
            "LogLevel": {
                "Default": "Debug"
            }
    }
}

标签:core,asp,Logging,LogLevel,ILogger,logging,日志,public,logger
来源: https://www.cnblogs.com/tangge/p/14033479.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有