.NET Core 和 ASP.NET Core 中的日志记录Logging in .NET Core and ASP.NET Core

作者:Kirk LarkinJuergen GutschRick AndersonBy Kirk Larkin, Juergen Gutsch and Rick Anderson

.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。.NET Core supports a logging API that works with a variety of built-in and third-party logging providers. 本文介绍了如何将日志记录 API 与内置提供程序一起使用。This article shows how to use the logging API with built-in providers.

本文中所述的大多数代码示例都来自 ASP.NET Core 应用。Most of the code examples shown in this article are from ASP.NET Core apps. 这些代码片段的日志记录特定部分适用于任何使用通用主机的 .NET Core 应用。The logging-specific parts of these code snippets apply to any .NET Core app that uses the Generic Host. ASP.NET Core Web 应用模板使用通用主机。The ASP.NET Core web app templates use the Generic Host.

查看或下载示例代码如何下载View or download sample code (how to download)

日志记录提供程序Logging providers

日志记录提供程序存储日志,但显示日志的 Console 提供程序除外。Logging providers store logs, except for the Console provider which displays logs. 例如,Azure Application Insights 提供程序将日志存储在 Azure Application Insights 中。For example, the Azure Application Insights provider stores logs in Azure Application Insights. 可以启用多个提供程序。Multiple providers can be enabled.

默认 ASP.NET Core Web 应用模板:The default ASP.NET Core web app templates:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上面的代码显示了使用 ASP.NET Core Web 应用模板创建的 Program 类。The preceding code shows the Program class created with the ASP.NET Core web app templates. 接下来的几节提供基于使用通用主机的 ASP.NET Core Web 应用模板的示例。The next several sections provide samples based on the ASP.NET Core web app templates, which use the Generic Host. 本文档稍后将介绍非托管控制台应用Non-host console apps are discussed later in this document.

若要替代Host.CreateDefaultBuilder 添加的默认日志记录提供程序集,请调用 ClearProviders 并添加所需的日志记录提供程序。To override the default set of logging providers added by Host.CreateDefaultBuilder, call ClearProviders and add the required logging providers. 例如,以下代码:For example, the following code:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

有关其他提供程序,请参阅:For additional providers, see:

创建日志Create logs

若要创建日志,请使用依赖项注入 (DI) 中的 ILogger<TCategoryName>对象。To create logs, use an ILogger<TCategoryName> object from dependency injection (DI).

如下示例中:The following example:

  • 创建一个记录器 ILogger<AboutModel>,该记录器使用类型为 AboutModel 的完全限定名称的日志类别。Creates a logger, ILogger<AboutModel>, which uses a log category of the fully qualified name of the type AboutModel. 日志类别是与每个日志关联的字符串。The log category is a string that is associated with each log.
  • 调用 LogInformation 以在 Information 级别登录。Calls LogInformation to log at the Information level. 日志“级别”代表所记录事件的严重程度。The Log level indicates the severity of the logged event.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public void OnGet()
    {
        Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
        _logger.LogInformation(Message);
    }
}

本文档稍后将更详细地介绍级别类别Levels and categories are explained in more detail later in this document.

有关 Blazor 的信息,请参阅本文档中的在 Blazor 和 Blazor WebAssembly 中创建日志。For information on Blazor, see Create logs in Blazor and Blazor WebAssembly in this document.

在 Main 和 Startup 中创建日志介绍如何在 MainStartup 中创建日志。Create logs in Main and Startup shows how to create logs in Main and Startup.

配置日志记录Configure logging

日志配置通常由 appsettings {Environment}.json 文件的 Logging 部分提供 。Logging configuration is commonly provided by the Logging section of appsettings.{Environment}.json files. 以下 appsettings.Development.json 文件由 ASP.NET Core Web 应用模板生成:The following appsettings.Development.json file is generated by the ASP.NET Core web app templates:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

在上述 JSON 中:In the preceding JSON:

  • 指定了 "Default""Microsoft""Microsoft.Hosting.Lifetime" 类别。The "Default", "Microsoft", and "Microsoft.Hosting.Lifetime" categories are specified.
  • "Microsoft" 类别适用于以 "Microsoft" 开头的所有类别。The "Microsoft" category applies to all categories that start with "Microsoft". 例如,此设置适用于 "Microsoft.AspNetCore.Routing.EndpointMiddleware" 类别。For example, this setting applies to the "Microsoft.AspNetCore.Routing.EndpointMiddleware" category.
  • "Microsoft" 类别在日志级别 Warning 或更高级别记录。The "Microsoft" category logs at log level Warning and higher.
  • "Microsoft.Hosting.Lifetime" 类别比 "Microsoft" 类别更具体,因此 "Microsoft.Hosting.Lifetime" 类别在日志级别“Information”和更高级别记录。The "Microsoft.Hosting.Lifetime" category is more specific than the "Microsoft" category, so the "Microsoft.Hosting.Lifetime" category logs at log level "Information" and higher.
  • 未指定特定的日志提供程序,因此 LogLevel 适用于所有启用的日志记录提供程序,但 Windows EventLog 除外。A specific log provider is not specified, so LogLevel applies to all the enabled logging providers except for the Windows EventLog.

Logging 属性可以具有 LogLevel 和日志提供程序属性。The Logging property can have LogLevel and log provider properties. LogLevel 指定要针对所选类别进行记录的最低级别The LogLevel specifies the minimum level to log for selected categories. 在前面的 JSON 中,指定了 InformationWarning 日志级别。In the preceding JSON, Information and Warning log levels are specified. LogLevel 表示日志的严重性,范围为 0 到 6:LogLevel indicates the severity of the log and ranges from 0 to 6:

Trace = 0、Debug = 1、Information = 2、Warning = 3、Error = 4、Critical = 5 和 None = 6。Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5, and None = 6.

指定 LogLevel 时,将为指定级别和更高级别的消息启用日志记录。When a LogLevel is specified, logging is enabled for messages at the specified level and higher. 在前面的 JSON 中,记录了 Information 及更高级别的 Default 类别。In the preceding JSON, the Default category is logged for Information and higher. 例如,记录了 InformationWarningErrorCritical 消息。For example, Information, Warning, Error, and Critical messages are logged. 如果未指定 LogLevel,则日志记录默认为 Information 级别。If no LogLevel is specified, logging defaults to the Information level. 有关详细信息,请参阅日志级别For more information, see Log levels.

提供程序属性可以指定 LogLevel 属性。A provider property can specify a LogLevel property. 提供程序下的 LogLevel 指定要为该提供程序记录的级别,并替代非提供程序日志设置。LogLevel under a provider specifies levels to log for that provider, and overrides the non-provider log settings. 请考虑使用以下 appsettings.json 文件:Consider the following appsettings.json file:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Logging.{providername}.LogLevel 中的设置将替代 Logging.LogLevel 中的设置。Settings in Logging.{providername}.LogLevel override settings in Logging.LogLevel. 在前面的 JSON 中,Debug 提供程序的默认日志级别设置为 InformationIn the preceding JSON, the Debug provider's default log level is set to Information:

Logging:Debug:LogLevel:Default:Information

前面的设置为每个 Logging:Debug: 类别(Microsoft.Hosting 除外)指定 Information 日志级别。The preceding setting specifies the Information log level for every Logging:Debug: category except Microsoft.Hosting. 当列出特定类别时,该特定类别将替代默认类别。When a specific category is listed, the specific category overrides the default category. 在前面的 JSON 中,Logging:Debug:LogLevel 类别 "Microsoft.Hosting""Default" 替代 Logging:LogLevel 中的设置In the preceding JSON, the Logging:Debug:LogLevel categories "Microsoft.Hosting" and "Default" override the settings in Logging:LogLevel

可以为以下任何一项指定最低日志级别:The minimum log level can be specified for any of:

  • 特定提供程序:例如,Logging:EventSource:LogLevel:Default:InformationSpecific providers: For example, Logging:EventSource:LogLevel:Default:Information
  • 特定类别:例如,Logging:LogLevel:Microsoft:WarningSpecific categories: For example, Logging:LogLevel:Microsoft:Warning
  • 所有提供程序和所有类别:Logging:LogLevel:Default:WarningAll providers and all categories: Logging:LogLevel:Default:Warning

低于最低级别的任何日志均不会执行以下操作:Any logs below the minimum level are not:

  • 传递到提供程序。Passed to the provider.
  • 记录或显示。Logged or displayed.

要阻止所有日志,请指定 LogLevel.NoneTo suppress all logs, specify LogLevel.None. LogLevel.None 的值为 6,该值高于 LogLevel.Critical (5)。LogLevel.None has a value of 6, which is higher than LogLevel.Critical (5).

如果提供程序支持日志作用域,则 IncludeScopes 将指示是否启用这些域。If a provider supports log scopes, IncludeScopes indicates whether they're enabled. 有关详细信息,请参阅日志范围For more information, see log scopes

以下 appsettings.json 文件包含默认情况下启用的所有提供程序:The following appsettings.json file contains all the providers enabled by default:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

在上述示例中:In the preceding sample:

  • 类别和级别不是建议的值。The categories and levels are not suggested values. 提供该示例是为了显示所有默认提供程序。The sample is provided to show all the default providers.
  • Logging.{providername}.LogLevel 中的设置将替代 Logging.LogLevel 中的设置。Settings in Logging.{providername}.LogLevel override settings in Logging.LogLevel. 例如,Debug.LogLevel.Default 中的级别将替代 LogLevel.Default 中的级别。For example, the level in Debug.LogLevel.Default overrides the level in LogLevel.Default.
  • 将使用每个默认提供程序别名。Each default provider alias is used. 每个提供程序都定义了一个别名;可在配置中使用该别名来代替完全限定的类型名称。Each provider defines an alias that can be used in configuration in place of the fully qualified type name. 内置提供程序别名包括:The built-in providers aliases are:
    • 控制台Console
    • 调试Debug
    • EventSourceEventSource
    • EventLogEventLog
    • AzureAppServicesFileAzureAppServicesFile
    • AzureAppServicesBlobAzureAppServicesBlob
    • ApplicationInsightsApplicationInsights

通过命令行、环境变量和其他配置设置日志级别Set log level by command line, environment variables, and other configuration

日志级别可以由任何配置提供程序设置。Log level can be set by any of the configuration providers.

所有平台上的环境变量分层键都不支持 : 分隔符。The : separator doesn't work with environment variable hierarchical keys on all platforms. __(双下划线):__, the double underscore, is:

  • 受所有平台支持。Supported by all platforms. 例如,Bash 不支持 : 分隔符,但支持 __For example, the : separator is not supported by Bash, but __ is.
  • 自动替换为 :Automatically replaced by a :

以下命令:The following commands:

  • 在 Windows 上,将环境密钥 Logging:LogLevel:Microsoft 设置为值 InformationSet the environment key Logging:LogLevel:Microsoft to a value of Information on Windows.
  • 使用通过 ASP.NET Core Web 应用模板创建的应用时,请测试设置。Test the settings when using an app created with the ASP.NET Core web application templates. 使用 set 之后,必须在项目目录中运行 dotnet run 命令。The dotnet run command must be run in the project directory after using set.
set Logging__LogLevel__Microsoft=Information
dotnet run

前面的环境设置:The preceding environment setting:

  • 仅在进程中设置,这些进程是从设置进程的命令窗口启动的。Is only set in processes launched from the command window they were set in.
  • 不由使用 Visual Studio 启动的浏览器读取。Isn't read by browsers launched with Visual Studio.

以下 setx 命令还可以在 Windows 上设置环境键和值。The following setx command also sets the environment key and value on Windows. set 不同,setx 设置是持久的。Unlike set, setx settings are persisted. /M 开关在系统环境中设置变量。The /M switch sets the variable in the system environment. 如果未使用 /M,则设置用户环境变量。If /M isn't used, a user environment variable is set.

setx Logging__LogLevel__Microsoft=Information /M

Azure 应用服务上,选择“设置”>“配置”页面上的“新应用程序设置” 。On Azure App Service, select New application setting on the Settings > Configuration page. Azure 应用服务应用程序设置:Azure App Service application settings are:

  • 已静态加密且通过加密的通道进行传输。Encrypted at rest and transmitted over an encrypted channel.
  • 已作为环境变量公开。Exposed as environment variables.

有关详细信息,请参阅 Azure 应用:使用 Azure 门户替代应用配置For more information, see Azure Apps: Override app configuration using the Azure Portal.

有关使用环境变量设置 ASP.NET Core 配置值的详细信息,请参阅环境变量For more information on setting ASP.NET Core configuration values using environment variables, see environment variables. 有关使用其他配置源(包括命令行、Azure Key Vault、Azure 应用配置、其他文件格式等)的信息,请参阅 ASP.NET Core 中的配置For information on using other configuration sources, including the command line, Azure Key Vault, Azure App Configuration, other file formats, and more, see ASP.NET Core 中的配置.

如何应用筛选规则How filtering rules are applied

创建 ILogger<TCategoryName> 对象时,ILoggerFactory 对象将根据提供程序选择一条规则,将其应用于该记录器。When an ILogger<TCategoryName> object is created, the ILoggerFactory object selects a single rule per provider to apply to that logger. 将按所选规则筛选 ILogger 实例写入的所有消息。All messages written by an ILogger instance are filtered based on the selected rules. 从可用规则中为每个提供程序和类别对选择最具体的规则。The most specific rule for each provider and category pair is selected from the available rules.

在为给定的类别创建 ILogger 时,以下算法将用于每个提供程序:The following algorithm is used for each provider when an ILogger is created for a given category:

  • 选择匹配提供程序或其别名的所有规则。Select all rules that match the provider or its alias. 如果找不到任何匹配项,则选择提供程序为空的所有规则。If no match is found, select all rules with an empty provider.
  • 根据上一步的结果,选择具有最长匹配类别前缀的规则。From the result of the preceding step, select rules with longest matching category prefix. 如果找不到任何匹配项,则选择未指定类别的所有规则。If no match is found, select all rules that don't specify a category.
  • 如果选择了多条规则,则采用最后一条 。If multiple rules are selected, take the last one.
  • 如果未选择任何规则,则使用 MinimumLevelIf no rules are selected, use MinimumLevel.

记录来自 dotnet run 和 Visual Studio 的输出Logging output from dotnet run and Visual Studio

将显示使用默认日志记录提供程序创建的日志:Logs created with the default logging providers are displayed:

  • 在 Visual Studio 中In Visual Studio
    • 在调试时,在“调试输出”窗口中。In the Debug output window when debugging.
    • 在“ASP.NET Core Web 服务器”窗口中。In the ASP.NET Core Web Server window.
  • 使用 dotnet run 运行应用时,在控制台窗口中。In the console window when the app is run with dotnet run.

以“Microsoft”类别开头的日志来自 ASP.NET Core 框架代码。Logs that begin with "Microsoft" categories are from ASP.NET Core framework code. ASP.NET Core 和应用程序代码使用相同的日志记录 API 和提供程序。ASP.NET Core and application code use the same logging API and providers.

日志类别Log category

创建 ILogger 对象时,将指定类别。When an ILogger object is created, a category is specified. 该类别包含在由此 ILogger 实例创建的每条日志消息中。That category is included with each log message created by that instance of ILogger. 类别字符串是任意的,但约定将使用类名称。The category string is arbitrary, but the convention is to use the class name. 例如,在控制器中,名称可能为 "TodoApi.Controllers.TodoController"For example, in a controller the name might be "TodoApi.Controllers.TodoController". ASP.NET Core Web 应用使用 ILogger<T> 自动获取使用完全限定类型名称 T 作为类别的 ILogger 实例:The ASP.NET Core web apps use ILogger<T> to automatically get an ILogger instance that uses the fully qualified type name of T as the category:

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.");
    }
}

要显式指定类别,请调用 ILoggerFactory.CreateLoggerTo explicitly specify the category, call 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.");
    }

ILogger<T> 相当于使用 T 的完全限定类型名称来调用 CreateLoggerILogger<T> is equivalent to calling CreateLogger with the fully qualified type name of T.

日志级别Log level

下表列出了 LogLevel 值、方便的 Log{LogLevel} 扩展方法以及建议的用法:The following table lists the LogLevel values, the convenience Log{LogLevel} extension method, and the suggested usage:

LogLevelLogLevel “值”Value 方法Method 描述Description
TraceTrace 00 LogTrace 包含最详细的消息。Contain the most detailed messages. 这些消息可能包含敏感的应用数据。These messages may contain sensitive app data. 这些消息默认情况下处于禁用状态,并且不应在生产中启用。These messages are disabled by default and should not be enabled in production.
调试Debug 11 LogDebug 用于调试和开发。For debugging and development. 由于量大,请在生产中小心使用。Use with caution in production due to the high volume.
信息Information 22 LogInformation 跟踪应用的常规流。Tracks the general flow of the app. 可能具有长期值。May have long-term value.
警告Warning 33 LogWarning 对于异常事件或意外事件。For abnormal or unexpected events. 通常包括不会导致应用失败的错误或情况。Typically includes errors or conditions that don't cause the app to fail.
错误Error 44 LogError 表示无法处理的错误和异常。For errors and exceptions that cannot be handled. 这些消息表示当前操作或请求失败,而不是整个应用失败。These messages indicate a failure in the current operation or request, not an app-wide failure.
严重Critical 55 LogCritical 需要立即关注的失败。For failures that require immediate attention. 例如数据丢失、磁盘空间不足。Examples: data loss scenarios, out of disk space.
None 66 指定日志记录类别不应写入任何消息。Specifies that a logging category should not write any messages.

在上表中,LogLevel 按严重性由低到高的顺序列出。In the previous table, the LogLevel is listed from lowest to highest severity.

Log 方法的第一个参数 LogLevel 指示日志的严重性。The Log method's first parameter, LogLevel, indicates the severity of the log. 大多数开发人员调用 Log{LogLevel} 扩展方法,而不调用 Log(LogLevel, ...)Rather than calling Log(LogLevel, ...), most developers call the Log{LogLevel} extension methods. Log{LogLevel} 扩展方法调用 Log 方法并指定 LogLevelThe Log{LogLevel} extension methods call the Log method and specify the LogLevel. 例如,以下两个日志记录调用功能相同,并生成相同的日志:For example, the following two logging calls are functionally equivalent and produce the same log:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem 是事件 ID。MyLogEvents.TestItem is the event ID. MyLogEvents 是示例应用的一部分,并显示在日志事件 ID 部分中。MyLogEvents is part of the sample app and is displayed in the Log event ID section.

MyDisplayRouteInfo 和 ToCtxStringRick.Docs.Samples.RouteInfo NuGet 包提供。MyDisplayRouteInfo and ToCtxString are provided by the Rick.Docs.Samples.RouteInfo NuGet package. 这些方法会显示 Controller 路线信息。The methods display Controller route information.

下面的代码会创建 InformationWarning 日志:The following code creates Information and Warning logs:

[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);
}

在前面的代码中,第一个 Log{LogLevel} 参数 MyLogEvents.GetItem日志事件 IDIn the preceding code, the first Log{LogLevel} parameter,MyLogEvents.GetItem, is the Log event ID. 第二个参数是消息模板,其中的占位符用于填写剩余方法形参提供的实参值。The second parameter is a message template with placeholders for argument values provided by the remaining method parameters. 本文档后面的消息模板部分介绍了方法参数。The method parameters are explained in the message template section later in this document.

调用相应的 Log{LogLevel} 方法,以控制写入到特定存储介质的日志输出量。Call the appropriate Log{LogLevel} method to control how much log output is written to a particular storage medium. 例如:For example:

  • 生产中:In production:
    • TraceInformation 级别记录日志会产生大量详细的日志消息。Logging at the Trace or Information levels produces a high-volume of detailed log messages. 为了控制成本且不超过数据存储限制,请将 TraceInformation 级别消息记录到容量大、成本低的数据存储中。To control costs and not exceed data storage limits, log Trace and Information level messages to a high-volume, low-cost data store. 考虑将 TraceInformation 限制为特定类别。Consider limiting Trace and Information to specific categories.
    • WarningCritical 级别的日志记录应该很少产生日志消息。Logging at Warning through Critical levels should produce few log messages.
      • 成本和存储限制通常不是问题。Costs and storage limits usually aren't a concern.
      • 很少有日志可以为数据存储选择提供更大的灵活性。Few logs allow more flexibility in data store choices.
  • 在开发过程中:In development:
    • 设置为 WarningSet to Warning.
    • 在进行故障排除时,添加 TraceInformation 消息。Add Trace or Information messages when troubleshooting. 若要限制输出,请仅对正在调查的类别设置 TraceInformationTo limit output, set Trace or Information only for the categories under investigation.

ASP.NET Core 为框架事件写入日志。ASP.NET Core writes logs for framework events. 例如,考虑以下对象的日志输出:For example, consider the log output for:

  • 使用 ASP.NET Core 模板创建的 Razor Pages 应用。A Razor Pages app created with the ASP.NET Core templates.
  • 日志记录设置为 Logging:Console:LogLevel:Microsoft:InformationLogging set to Logging:Console:LogLevel:Microsoft:Information
  • 导航到“隐私”页面:Navigation to the Privacy page:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

以下 JSON 设置了 Logging:Console:LogLevel:Microsoft:InformationThe following JSON sets Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

日志事件 IDLog event ID

每个日志都可指定一个事件 ID 。Each log can specify an event ID. 示例应用使用 MyLogEvents 类来定义事件 ID:The sample app uses the MyLogEvents class to define event IDs:

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 与一组事件相关联。An event ID associates a set of events. 例如,与在页面上显示项列表相关的所有日志可能是 1001。For example, all logs related to displaying a list of items on a page might be 1001.

日志记录提供程序可将事件 ID 存储在 ID 字段中,存储在日志记录消息中,或者不进行存储。The logging provider may store the event ID in an ID field, in the logging message, or not at all. 调试提供程序不显示事件 ID。The Debug provider doesn't show event IDs. 控制台提供程序在类别后的括号中显示事件 ID:The console provider shows event IDs in brackets after the category:

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

一些日志记录提供程序将事件 ID 存储在一个字段中,该字段允许对 ID 进行筛选。Some logging providers store the event ID in a field, which allows for filtering on the ID.

日志消息模板Log message template

每个日志 API 都使用一个消息模板。Each log API uses a message template. 消息模板可包含要填写参数的占位符。The message template can contain placeholders for which arguments are provided. 请在占位符中使用名称而不是数字。Use names for the placeholders, not numbers.

[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);
}

占位符的顺序(而非其名称)决定了为其提供值的参数。The order of placeholders, not their names, determines which parameters are used to provide their values. 在以下代码中,消息模板中的参数名称不按顺序排列:In the following code, the parameter names are out of sequence in the message template:

string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);

上面的代码按顺序通过参数值创建日志消息:The preceding code creates a log message with the parameter values in sequence:

Parameter values: param1, param2

此方法允许日志记录提供程序实现语义或结构化日志记录This approach allows logging providers to implement semantic or structured logging. 参数本身会传递给日志记录系统,而不仅仅是格式化的消息模板。The arguments themselves are passed to the logging system, not just the formatted message template. 这使日志记录提供程序可以将参数值存储为字段。This enables logging providers to store the parameter values as fields. 例如,考虑使用以下记录器方法:For example, consider the following logger method:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

例如,登录到 Azure 表存储时:For example, when logging to Azure Table Storage:

  • 每个 Azure 表实体都可以有 IDRequestTime 属性。Each Azure Table entity can have ID and RequestTime properties.
  • 具有属性的表简化了对记录数据的查询。Tables with properties simplify queries on logged data. 例如,查询可以找到特定 RequestTime 范围内的所有日志,而不必分析文本消息中的时间。For example, a query can find all logs within a particular RequestTime range without having to parse the time out of the text message.

记录异常Log exceptions

记录器方法的重载采用异常参数:The logger methods have overloads that take an exception parameter:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo 和 ToCtxStringRick.Docs.Samples.RouteInfo NuGet 包提供。MyDisplayRouteInfo and ToCtxString are provided by the Rick.Docs.Samples.RouteInfo NuGet package. 这些方法会显示 Controller 路线信息。The methods display Controller route information.

异常日志记录是特定于提供程序的。Exception logging is provider-specific.

默认日志级别Default log level

如果未设置默认日志级别,则默认的日志级别值为 InformationIf the default log level is not set, the default log level value is Information.

例如,考虑以下 Web 应用:For example, consider the following web app:

  • 使用 ASP.NET Web 应用模板创建的应用。Created with the ASP.NET web app templates.
  • 已删除 appsettings.json 和 appsettings.Development.json 或对其进行重命名 。appsettings.json and appsettings.Development.json deleted or renamed.

使用上述设置,导航到隐私或主页会生成许多 TraceDebugInformation 消息,并在类别名称中包含 MicrosoftWith the preceding setup, navigating to the privacy or home page produces many Trace, Debug, and Information messages with Microsoft in the category name.

如果未在配置中设置默认日志级别,以下代码会设置默认日志级别:The following code sets the default log level when the default log level is not set in configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

通常,日志级别应在配置中指定,而不是在代码中指定。Generally, log levels should be specified in configuration and not code.

筛选器函数Filter function

对配置或代码没有向其分配规则的所有提供程序和类别调用筛选器函数:A filter function is invoked for all providers and categories that don't have rules assigned to them by configuration or code:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddFilter((provider, category, logLevel) =>
                {
                    if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Controller")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Microsoft")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

如果类别包含 ControllerMicrosoft,并且日志级别为 Information 或更高级别,以上代码会显示控制台日志。The preceding code displays console logs when the category contains Controller or Microsoft and the log level is Information or higher.

通常,日志级别应在配置中指定,而不是在代码中指定。Generally, log levels should be specified in configuration and not code.

ASP.NET Core 和 EF Core 类别ASP.NET Core and EF Core categories

下表包含 ASP.NET Core 和 Entity Framework Core 使用的一些类别,并带有有关日志的注释:The following table contains some categories used by ASP.NET Core and Entity Framework Core, with notes about the logs:

类别Category 说明Notes
Microsoft.AspNetCoreMicrosoft.AspNetCore 常规 ASP.NET Core 诊断。General ASP.NET Core diagnostics.
Microsoft.AspNetCore.DataProtectionMicrosoft.AspNetCore.DataProtection 考虑、找到并使用了哪些密钥。Which keys were considered, found, and used.
Microsoft.AspNetCore.HostFilteringMicrosoft.AspNetCore.HostFiltering 所允许的主机。Hosts allowed.
Microsoft.AspNetCore.HostingMicrosoft.AspNetCore.Hosting HTTP 请求完成的时间和启动时间。How long HTTP requests took to complete and what time they started. 加载了哪些承载启动程序集。Which hosting startup assemblies were loaded.
Microsoft.AspNetCore.MvcMicrosoft.AspNetCore.Mvc MVC 和 Razor 诊断。MVC and Razor diagnostics. 模型绑定、筛选器执行、视图编译和操作选择。Model binding, filter execution, view compilation, action selection.
Microsoft.AspNetCore.RoutingMicrosoft.AspNetCore.Routing 路由匹配信息。Route matching information.
Microsoft.AspNetCore.ServerMicrosoft.AspNetCore.Server 连接启动、停止和保持活动响应。Connection start, stop, and keep alive responses. HTTP 证书信息。HTTPS certificate information.
Microsoft.AspNetCore.StaticFilesMicrosoft.AspNetCore.StaticFiles 提供的文件。Files served.
Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore 常规 Entity Framework Core 诊断。General Entity Framework Core diagnostics. 数据库活动和配置、更改检测、迁移。Database activity and configuration, change detection, migrations.

若要在控制台窗口中查看更多类别,请将 appsettings.Development.json 设置为以下各项:To view more categories in the console window, set appsettings.Development.json to the following:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

日志作用域Log scopes

“作用域”可对一组逻辑操作分组 。A scope can group a set of logical operations. 此分组可用于将相同的数据附加到作为集合的一部分而创建的每个日志。This grouping can be used to attach the same data to each log that's created as part of a set. 例如,在处理事务期间创建的每个日志都可包括事务 ID。For example, every log created as part of processing a transaction can include the transaction ID.

范围:A scope:

以下提供程序支持范围:The following providers support scopes:

要使用作用域,请在 using 块中包装记录器调用:Use a scope by wrapping logger calls in a using block:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;

    using (_logger.BeginScope("using block message"))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

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

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

    return ItemToDTO(todoItem);
}

以下 JSON 为控制台提供程序启用范围:The following JSON enables scopes for the console provider:

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

下列代码为控制台提供程序启用作用域:The following code enables scopes for the console provider:

public class Scopes
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

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

通常,日志记录应在配置中指定,而不是在代码中指定。Generally, logging should be specified in configuration and not code.

内置日志记录提供程序Built-in logging providers

ASP.NET Core 包含以下日志记录提供程序:ASP.NET Core includes the following logging providers:

要了解 stdout 以及如何通过 ASP.NET Core 模块调试日志记录,请参阅 对 Azure 应用服务和 IIS 上的 ASP.NET Core 进行故障排除ASP.NET Core 模块For information on stdout and debug logging with the ASP.NET Core Module, see 对 Azure 应用服务和 IIS 上的 ASP.NET Core 进行故障排除 and ASP.NET Core 模块.

控制台Console

Console 提供程序将输出记录到控制台。The Console provider logs output to the console. 如需详细了解如何在开发环境中查看 Console 日志,请参阅记录来自 dotnet run 和 Visual Studio 的输出For more information on viewing Console logs in development, see Logging output from dotnet run and Visual Studio.

调试Debug

Debug 提供程序通过使用 System.Diagnostics.Debug 类来写入日志输出。The Debug provider writes log output by using the System.Diagnostics.Debug class. System.Diagnostics.Debug.WriteLine 的调用写入到 Debug 提供程序。Calls to System.Diagnostics.Debug.WriteLine write to the Debug provider.

在 Linux 上,Debug 提供程序日志位置取决于分发,并且可以是以下位置之一:On Linux, the Debug provider log location is distribution-dependent and may be one of the following:

  • /var/log/message/var/log/message
  • /var/log/syslog/var/log/syslog

事件来源Event Source

EventSource 提供程序写入名称为 Microsoft-Extensions-Logging 的跨平台事件源。The EventSource provider writes to a cross-platform event source with the name Microsoft-Extensions-Logging. 在 Windows 上,提供程序使用的是 ETWOn Windows, the provider uses ETW.

dotnet 跟踪工具dotnet trace tooling

dotnet-trace 工具是一种跨平台 CLI 全局工具,可用于收集正在运行的进程的 .NET Core 跟踪。The dotnet-trace tool is a cross-platform CLI global tool that enables the collection of .NET Core traces of a running process. 该工具会使用 LoggingEventSource 收集 Microsoft.Extensions.Logging.EventSource 提供程序数据。The tool collects Microsoft.Extensions.Logging.EventSource provider data using a LoggingEventSource.

有关安装说明,请参阅 dotnet-traceSee dotnet-trace for installation instructions.

使用 dotnet 跟踪工具从应用中收集跟踪:Use the dotnet trace tooling to collect a trace from an app:

  1. 使用 dotnet run 命令运行此应用。Run the app with the dotnet run command.

  2. 确定 .NET Core 应用的进程标识符 (PID):Determine the process identifier (PID) of the .NET Core app:

    找到进程的 PID,它与应用的程序集的名称相同。Find the PID for the process that has the same name as the app's assembly.

  3. 执行 dotnet trace 命令。Execute the dotnet trace command.

    常规命令语法:General command syntax:

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Event Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Event Level 1};
                {Logger Category 2}:{Event Level 2};
                ...
                {Logger Category N}:{Event Level N}\"
    

    使用 PowerShell 命令行界面时,将 --providers 值用单引号 (') 引起来:When using a PowerShell command shell, enclose the --providers value in single quotes ('):

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Event Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Event Level 1};
                {Logger Category 2}:{Event Level 2};
                ...
                {Logger Category N}:{Event Level N}\"'
    

    在非 Windows 平台上,添加 -f speedscope 选项,将输出跟踪文件更改为 speedscopeOn non-Windows platforms, add the -f speedscope option to change the format of the output trace file to speedscope.

    关键字Keyword 说明Description
    11 记录有关 LoggingEventSource 的 meta 事件。Log meta events about the LoggingEventSource. 请不要从 ILogger 记录事件。Doesn't log events from ILogger).
    22 在调用 ILogger.Log() 时启用 Message 事件。Turns on the Message event when ILogger.Log() is called. 以编程(未格式化)方式提供信息。Provides information in a programmatic (not formatted) way.
    44 在调用 ILogger.Log() 时启用 FormatMessage 事件。Turns on the FormatMessage event when ILogger.Log() is called. 提供格式化字符串版本的信息。Provides the formatted string version of the information.
    88 在调用 ILogger.Log() 时启用 MessageJson 事件。Turns on the MessageJson event when ILogger.Log() is called. 提供参数的 JSON 表示形式。Provides a JSON representation of the arguments.
    事件级别Event Level 描述Description
    00 LogAlways
    11 Critical
    22 Error
    33 Warning
    44 Informational
    55 Verbose

    {Logger Category}{Event Level}FilterSpecs 条目表示其他日志筛选条件。FilterSpecs entries for {Logger Category} and {Event Level} represent additional log filtering conditions. 请用分号 (;) 分隔 FilterSpecs 条目。Separate FilterSpecs entries with a semicolon (;).

    下例使用 Windows 命令界面(--providers 值不用单引号引起来) :Example using a Windows command shell (no single quotes around the --providers value):

    dotnet trace collect -p {PID} --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    上面的命令会激活:The preceding command activates:

    • 事件源记录器,它用于为错误 (2) 生成格式化字符串 (4)。The Event Source logger to produce formatted strings (4) for errors (2).
    • Informational 日志记录级别 (4) 的 Microsoft.AspNetCore.Hosting 日志记录。Microsoft.AspNetCore.Hosting logging at the Informational logging level (4).
  4. 通过按 Enter 键或 Ctrl+C 停止 dotnet 跟踪工具。Stop the dotnet trace tooling by pressing the Enter key or Ctrl+C.

    跟踪使用名称 trace.nettrace 保存在执行 dotnet trace 命令的文件夹中 。The trace is saved with the name trace.nettrace in the folder where the dotnet trace command is executed.

  5. 使用预览功能打开跟踪。Open the trace with Perfview. 打开 trace.nettrace 文件并浏览跟踪事件 。Open the trace.nettrace file and explore the trace events.

如果应用不使用 CreateDefaultBuilder 生成主机,则请向应用的日志记录配置添加事件源提供程序If the app doesn't build the host with CreateDefaultBuilder, add the Event Source provider to the app's logging configuration.

有关详细信息,请参见:For more information, see:

PerfviewPerfview

使用 PerfView 实用工具收集和查看日志。Use the PerfView utility to collect and view logs. 虽然其他工具也可以查看 ETW 日志,但在处理由 ASP.NET Core 发出的 ETW 事件时,使用 PerfView 能获得最佳体验。There are other tools for viewing ETW logs, but PerfView provides the best experience for working with the ETW events emitted by ASP.NET Core.

要将 PerfView 配置为收集此提供程序记录的事件,请向 Additional Providers 列表添加字符串 *Microsoft-Extensions-LoggingTo configure PerfView for collecting events logged by this provider, add the string *Microsoft-Extensions-Logging to the Additional Providers list. 请勿遗漏字符串起始处的 *Don't miss the * at the start of the string.

Windows 事件日志Windows EventLog

EventLog 提供程序将日志输出发送到 Windows 事件日志。The EventLog provider sends log output to the Windows Event Log. 与其他提供程序不同,EventLog 提供程序不继承默认的非提供程序设置。Unlike the other providers, the EventLog provider does not inherit the default non-provider settings. 如果未指定 EventLog 日志设置,则它们默认为 LogLevel.WarningIf EventLog log settings aren't specified, they default to LogLevel.Warning.

若要记录低于 LogLevel.Warning 的事件,请显式设置日志级别。To log events lower than LogLevel.Warning, explicitly set the log level. 以下示例将事件日志的默认日志级别设置为 LogLevel.InformationThe following example sets the Event Log default log level to LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

AddEventLog 重载可以传入 EventLogSettingsAddEventLog overloads can pass in EventLogSettings. 如果为 null 或未指定,则使用以下默认设置:If null or not specified, the following default settings are used:

  • LogName:“Application”LogName: "Application"
  • SourceName:“.NET Runtime”SourceName: ".NET Runtime"
  • MachineName:使用本地计算机名称。MachineName: The local machine name is used.

以下代码将 SourceName 从默认值 ".NET Runtime" 更改为 MyLogsThe following code changes the SourceName from the default value of ".NET Runtime" to MyLogs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddEventLog(eventLogSettings =>
                {
                    eventLogSettings.SourceName = "MyLogs"; 
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Azure 应用服务Azure App Service

Microsoft.Extensions.Logging.AzureAppServices 提供程序包将日志写入 Azure App Service 应用的文件系统,以及 Azure 存储帐户中的 blob 存储The Microsoft.Extensions.Logging.AzureAppServices provider package writes logs to text files in an Azure App Service app's file system and to blob storage in an Azure Storage account.

共享框架中不包括该提供程序包。The provider package isn't included in the shared framework. 若要使用提供程序,请将提供程序包添加到项目。To use the provider, add the provider package to the project.

要配置提供程序设置,请使用 AzureFileLoggerOptionsAzureBlobLoggerOptions,如以下示例所示:To configure provider settings, use AzureFileLoggerOptions and AzureBlobLoggerOptions, as shown in the following example:

public class Scopes
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
                .ConfigureServices(serviceCollection => serviceCollection
                    .Configure<AzureFileLoggerOptions>(options =>
                    {
                        options.FileName = "azure-diagnostics-";
                        options.FileSizeLimit = 50 * 1024;
                        options.RetainedFileCountLimit = 5;
                    })
                    .Configure<AzureBlobLoggerOptions>(options =>
                    {
                        options.BlobName = "log.txt";
                    }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

部署到 Azure 应用服务时,应用使用 Azure 门户的“应用服务”页面的应用服务日志部分中的设置。When deployed to Azure App Service, the app uses the settings in the App Service logs section of the App Service page of the Azure portal. 更新以下设置后,更改立即生效,无需重启或重新部署应用。When the following settings are updated, the changes take effect immediately without requiring a restart or redeployment of the app.

  • 应用程序日志记录(Filesystem)Application Logging (Filesystem)
  • 应用程序日志记录(Blob)Application Logging (Blob)

日志文件的默认位置是 D:\home\LogFiles\Application 文件夹,默认文件名为 diagnostics-yyyymmdd.txt 。The default location for log files is in the D:\home\LogFiles\Application folder, and the default file name is diagnostics-yyyymmdd.txt. 默认文件大小上限为 10 MB,默认最大保留文件数为 2。The default file size limit is 10 MB, and the default maximum number of files retained is 2. 默认 blob 名为 {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt 。The default blob name is {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

仅当项目在 Azure 环境中运行时,此提供程序才记录日志。This provider only logs when the project runs in the Azure environment.

Azure 日志流式处理Azure log streaming

Azure 日志流式处理支持从以下位置实时查看日志活动:Azure log streaming supports viewing log activity in real time from:

  • 应用服务器The app server
  • Web 服务器The web server
  • 请求跟踪失败Failed request tracing

要配置 Azure 日志流式处理,请执行以下操作:To configure Azure log streaming:

  • 从应用的门户页导航到“应用服务日志”页。Navigate to the App Service logs page from the app's portal page.
  • 将“应用程序日志记录(Filesystem)”设置为“开” 。Set Application Logging (Filesystem) to On.
  • 选择日志级别 。Choose the log Level. 此设置仅适用于 Azure 日志流式处理。This setting only applies to Azure log streaming.

导航到“日志流”页面以查看日志。Navigate to the Log Stream page to view logs. 记录的消息使用 ILogger 接口进行记录。The logged messages are logged with the ILogger interface.

Azure Application InsightsAzure Application Insights

Microsoft.Extensions.Logging.ApplicationInsights 提供程序包将日志写入 Azure Application InsightsThe Microsoft.Extensions.Logging.ApplicationInsights provider package writes logs to Azure Application Insights. Application Insights 是一项服务,可监视 Web 应用并提供用于查询和分析遥测数据的工具。Application Insights is a service that monitors a web app and provides tools for querying and analyzing the telemetry data. 如果使用此提供程序,则可以使用 Application Insights 工具来查询和分析日志。If you use this provider, you can query and analyze your logs by using the Application Insights tools.

日志记录提供程序作为 Microsoft.ApplicationInsights.AspNetCore(这是提供 ASP.NET Core 的所有可用遥测的包)的依赖项包括在内。The logging provider is included as a dependency of Microsoft.ApplicationInsights.AspNetCore, which is the package that provides all available telemetry for ASP.NET Core. 如果使用此包,则无需安装提供程序包。If you use this package, you don't have to install the provider package.

Microsoft.ApplicationInsights.Web 包适用于 ASP.NET 4.x,而不适用于 ASP.NET Core。The Microsoft.ApplicationInsights.Web package is for ASP.NET 4.x, not ASP.NET Core.

有关更多信息,请参见以下资源:For more information, see the following resources:

第三方日志记录提供程序Third-party logging providers

适用于 ASP.NET Core 的第三方日志记录框架:Third-party logging frameworks that work with ASP.NET Core:

某些第三方框架可以执行语义日志记录(又称结构化日志记录)Some third-party frameworks can perform semantic logging, also known as structured logging.

使用第三方框架类似于使用以下内置提供程序之一:Using a third-party framework is similar to using one of the built-in providers:

  1. 将 NuGet 包添加到你的项目。Add a NuGet package to your project.
  2. 调用日志记录框架提供的 ILoggerFactory 扩展方法。Call an ILoggerFactory extension method provided by the logging framework.

有关详细信息,请参阅各提供程序的相关文档。For more information, see each provider's documentation. Microsoft 不支持第三方日志记录提供程序。Third-party logging providers aren't supported by Microsoft.

非托管控制台应用Non-host console app

要通过示例了解如何在非 Web 控制台应用中使用一般主机,请参阅后台任务示例应用 的 Program.cs 文件 (在 ASP.NET Core 中使用托管服务实现后台任务) 。For an example of how to use the Generic Host in a non-web console app, see the Program.cs file of the Background Tasks sample app (在 ASP.NET Core 中使用托管服务实现后台任务).

对于没有通用主机的应用,日志记录代码在添加提供程序创建记录器的方式上有所不同。Logging code for apps without Generic Host differs in the way providers are added and loggers are created.

日志记录提供程序Logging providers

在非主机控制台应用中,在创建 LoggerFactory 时调用提供程序的 Add{provider name} 扩展方法:In a non-host console app, call the provider's Add{provider name} extension method while creating a LoggerFactory:

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

创建日志Create logs

若要创建日志,请使用 ILogger<TCategoryName> 对象。To create logs, use an ILogger<TCategoryName> object. 使用 LoggerFactory 创建一个 ILoggerUse the LoggerFactory to create an ILogger.

以下示例创建类别为 LoggingConsoleApp.Program 的记录器。The following example creates a logger with LoggingConsoleApp.Program as the category.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

在以下 ASP.NET CORE 示例中,记录器用于创建级别为 Information 的日志。In the following ASP.NET CORE examples, the logger is used to create logs with Information as the level. 日志“级别”代表所记录事件的严重程度。The Log level indicates the severity of the logged event.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

本文档中详细介绍了级别类别Levels and categories are explained in more detail in this document.

主机构造过程中的日志Log during host construction

不直接支持在主机构造期间进行日志记录。Logging during host construction isn't directly supported. 但是,可以使用单独的记录器。However, a separate logger can be used. 在以下示例中,Serilog 记录器用于登录 CreateHostBuilderIn the following example, a Serilog logger is used to log in CreateHostBuilder. AddSerilog 使用 Log.Logger 中指定的静态配置:AddSerilog uses the static configuration specified in Log.Logger:

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddRazorPages();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {   
                    logging.AddSerilog();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

配置依赖于 ILogger 的服务Configure a service that depends on ILogger

由于为 Web 主机创建了单独的 DI 容器,所以在 ASP.NET Core 的早期版本中,构造函数将记录器注入到 Startup 工作。Constructor injection of a logger into Startup works in earlier versions of ASP.NET Core because a separate DI container is created for the Web Host. 若要了解为何仅为通用主机创建一个容器,请参阅重大更改公告For information about why only one container is created for the Generic Host, see the breaking change announcement.

若要配置依赖于 ILogger<T> 的服务,请使用构造函数注入或提供工厂方法。To configure a service that depends on ILogger<T>, use constructor injection or provide a factory method. 只有在没有其他选择的情况下,才建议使用工厂方法。The factory method approach is recommended only if there is no other option. 例如,假设某个服务需要由 DI 提供的 ILogger<T> 实例:For example, consider a service that needs an ILogger<T> instance provided by DI:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddRazorPages();

    services.AddSingleton<IMyService>((container) =>
    {
        var logger = container.GetRequiredService<ILogger<MyService>>();
        return new MyService() { Logger = logger };
    });
}

前面突出显示的代码是 Func,该代码在 DI 容器第一次需要构造 MyService 实例时运行。The preceding highlighted code is a Func that runs the first time the DI container needs to construct an instance of MyService. 可以用这种方式访问任何已注册的服务。You can access any of the registered services in this way.

在 Main 中创建日志Create logs in Main

以下代码通过在构建主机之后从 DI 获取 ILogger 实例来登录 MainThe following code logs in Main by getting an ILogger instance from DI after building the host:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Host created.");

    host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

启动时创建日志Create logs in Startup

以下代码在 Startup.Configure 中写入日志:The following code writes logs in Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                      ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        logger.LogInformation("In Development.");
        app.UseDeveloperExceptionPage();
    }
    else
    {
        logger.LogInformation("Not Development.");
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

不支持在 Startup.ConfigureServices 方法中完成 DI 容器设置之前就写入日志:Writing logs before completion of the DI container setup in the Startup.ConfigureServices method is not supported:

  • 不支持将记录器注入到 Startup 构造函数中。Logger injection into the Startup constructor is not supported.
  • 不支持将记录器注入到 Startup.ConfigureServices 方法签名中Logger injection into the Startup.ConfigureServices method signature is not supported

这一限制的原因是,日志记录依赖于 DI 和配置,而配置又依赖于 DI。The reason for this restriction is that logging depends on DI and on configuration, which in turns depends on DI. 在完成 ConfigureServices 之前,不会设置 DI 容器。The DI container isn't set up until ConfigureServices finishes.

有关配置依赖于 ILogger<T> 的服务或为什么在早期版本中可以使用构造函数将记录器注入 Startup 的信息,请参阅配置依赖 ILogger 的服务For information on configuring a service that depends on ILogger<T> or why constructor injection of a logger into Startup worked in earlier versions, see Configure a service that depends on ILogger

没有异步记录器方法No asynchronous logger methods

日志记录应该会很快,不值得牺牲性能来使用异步代码。Logging should be so fast that it isn't worth the performance cost of asynchronous code. 如果日志记录数据存储很慢,请不要直接写入它。If a logging data store is slow, don't write to it directly. 考虑先将日志消息写入快速存储,然后再将其移至慢速存储。Consider writing the log messages to a fast store initially, then moving them to the slow store later. 例如,登录到 SQL Server 时,请勿直接使用 Log 方法登录,因为 Log 方法是同步的。For example, when logging to SQL Server, don't do so directly in a Log method, since the Log methods are synchronous. 相反,你会将日志消息同步添加到内存中的队列,并让后台辅助线程从队列中拉出消息,以完成将数据推送到 SQL Server 的异步工作。Instead, synchronously add log messages to an in-memory queue and have a background worker pull the messages out of the queue to do the asynchronous work of pushing data to SQL Server. 有关详细信息,请参阅 GitHub 问题。For more information, see this GitHub issue.

更改正在运行的应用中的日志级别Change log levels in a running app

不可使用日志记录 API 在应用运行时更改日志记录。The Logging API doesn't include a scenario to change log levels while an app is running. 但是,一些配置提供程序可重新加载配置,这将对日志记录配置立即产生影响。However, some configuration providers are capable of reloading configuration, which takes immediate effect on logging configuration. 例如,文件配置提供程序默认情况下重载日志记录配置。For example, the File Configuration Provider, reloads logging configuration by default. 如果在应用运行时在代码中更改了配置,则该应用可调用 IConfigurationRoot.Reload 来更新应用的日志记录配置。If configuration is changed in code while an app is running, the app can call IConfigurationRoot.Reload to update the app's logging configuration.

ILogger 和 ILoggerFactoryILogger and ILoggerFactory

ILogger<TCategoryName>ILoggerFactory 接口和实现都包含在 .NET Core SDK 中。The ILogger<TCategoryName> and ILoggerFactory interfaces and implementations are included in the .NET Core SDK. 它们还可以通过以下 NuGet 包获得:They are also available in the following NuGet packages:

在代码中应用日志筛选器规则Apply log filter rules in code

设置日志筛选器规则的首选方法是使用配置The preferred approach for setting log filter rules is by using Configuration.

下面的示例演示了如何在代码中注册筛选规则:The following example shows how to register filter rules in code:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
               logging.AddFilter("System", LogLevel.Debug)
                  .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
                  .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

logging.AddFilter("System", LogLevel.Debug) 指定 System 类别和日志级别 Debuglogging.AddFilter("System", LogLevel.Debug) specifies the System category and log level Debug. 筛选器将应用于所有提供程序,因为未配置特定的提供程序。The filter is applied to all providers because a specific provider was not configured.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) 指定以下项:AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) specifies:

  • Debug 日志记录提供程序。The Debug logging provider.
  • 日志级别 Information 及更高级别。Log level Information and higher.
  • "Microsoft" 开头的所有类别。All categories starting with "Microsoft".

创建自定义记录器Create a custom logger

若要添加自定义记录器,请添加包含 ILoggerFactoryILoggerProviderTo add a custom logger, add an ILoggerProvider with ILoggerFactory:

public void Configure(
    IApplicationBuilder app,
    IWebHostEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory.AddProvider(new CustomLoggerProvider(new CustomLoggerConfiguration()));

ILoggerProvider 创建一个或多个 ILogger 实例。The ILoggerProvider creates one or more ILogger instances. 框架使用 ILogger 实例记录信息。The ILogger instances are used by the framework to log the information.

示例自定义记录器配置Sample custom logger configuration

示例:The sample:

  • 设计为非常基本的示例,可通过事件 ID 和日志级别设置日志控制台的颜色。Is designed to be a very basic sample that sets the color of the log console by event ID and log level. 记录器通常不会随事件 ID 改变,也不特定于日志级别。Loggers generally don't change by event ID and are not specific to log level.
  • 使用以下配置类型为每个日志级别和事件 ID 创建不同的颜色控制台条目:Creates different color console entries per log level and event ID using the following configuration type:
public class ColorConsoleLoggerConfiguration
{
    public LogLevel LogLevel { get; set; } = LogLevel.Warning;
    public int EventId { get; set; } = 0;
    public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}

前面的代码将默认级别设置为 Warning,并将颜色设置为 YellowThe preceding code sets the default level to Warning and the color to Yellow. 如果 EventId 设置为 0,我们将记录所有事件。If the EventId is set to 0, we will log all events.

创建自定义记录器Create the custom logger

ILogger 实现类别名称通常是日志记录源。The ILogger implementation category name is typically the logging source. 例如,创建记录器的类型:For example, the type where the logger is created:

public class ColorConsoleLogger : ILogger
{
    private readonly string _name;
    private readonly ColorConsoleLoggerConfiguration _config;

    public ColorConsoleLogger(string name, ColorConsoleLoggerConfiguration config)
    {
        _name = name;
        _config = config;
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return null;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel == _config.LogLevel;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, 
                        Exception exception, Func<TState, Exception, string> formatter)
    {
        if (!IsEnabled(logLevel))
        {
            return;
        }

        if (_config.EventId == 0 || _config.EventId == eventId.Id)
        {
            var color = Console.ForegroundColor;
            Console.ForegroundColor = _config.Color;
            Console.WriteLine($"{logLevel} - {eventId.Id} " +
                              $"- {_name} - {formatter(state, exception)}");
            Console.ForegroundColor = color;
        }
    }
}

前面的代码:The preceding code:

  • 为每个类别名称创建一个记录器实例。Creates a logger instance per category name.
  • IsEnabled 中检查 logLevel == _config.LogLevel,因此每个 logLevel 都有一个唯一的记录器。Checks logLevel == _config.LogLevel in IsEnabled, so each logLevel has a unique logger. 通常,还应为所有更高的日志级别启用记录器:Generally, loggers should also be enabled for all higher log levels:
public bool IsEnabled(LogLevel logLevel)
{
    return logLevel >= _config.LogLevel;
}

创建自定义 LoggerProviderCreate the custom LoggerProvider

LoggerProvider 是创建记录器实例的类。The LoggerProvider is the class that creates the logger instances. 也许不需要为每个类别创建记录器实例,但这对于某些记录器(例如 NLog 或 log4net)是需要的。Maybe it is not needed to create a logger instance per category, but this makes sense for some Loggers, like NLog or log4net. 这样,你还可以按需为每个类别选择不同的日志记录输出目标:Doing this you are also able to choose different logging output targets per category if needed:

public class ColorConsoleLoggerProvider : ILoggerProvider
{
    private readonly ColorConsoleLoggerConfiguration _config;
    private readonly ConcurrentDictionary<string, ColorConsoleLogger> _loggers = new ConcurrentDictionary<string, ColorConsoleLogger>();

    public ColorConsoleLoggerProvider(ColorConsoleLoggerConfiguration config)
    {
        _config = config;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return _loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, _config));
    }

    public void Dispose()
    {
        _loggers.Clear();
    }
}

在前面的代码中,CreateLogger 为每个类别名称创建 ColorConsoleLogger 的单个实例并将其存储在 ConcurrentDictionary<TKey,TValue> 中;In the preceding code, CreateLogger creates a single instance of the ColorConsoleLogger per category name and stores it in the ConcurrentDictionary<TKey,TValue>;

自定义记录器的使用和注册Usage and registration of the custom logger

Startup.Configure 中注册记录器:Register the logger in the Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
                      ILoggerFactory loggerFactory)
{
    // Default registration.
    loggerFactory.AddProvider(new ColorConsoleLoggerProvider(
                              new ColorConsoleLoggerConfiguration
    {
        LogLevel = LogLevel.Error,
        Color = ConsoleColor.Red
    }));

    // Custom registration with default values.
    loggerFactory.AddColorConsoleLogger();

    // Custom registration with a new configuration instance.
    loggerFactory.AddColorConsoleLogger(new ColorConsoleLoggerConfiguration
    {
        LogLevel = LogLevel.Debug,
        Color = ConsoleColor.Gray
    });

    // Custom registration with a configuration object.
    loggerFactory.AddColorConsoleLogger(c =>
    {
        c.LogLevel = LogLevel.Information;
        c.Color = ConsoleColor.Blue;
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

对于前面的代码,为 ILoggerFactory 提供至少一个扩展方法:For the preceding code, provide at least one extension method for the ILoggerFactory:

public static class ColorConsoleLoggerExtensions
{
    public static ILoggerFactory AddColorConsoleLogger(
                                      this ILoggerFactory loggerFactory, 
                                      ColorConsoleLoggerConfiguration config)
    {
        loggerFactory.AddProvider(new ColorConsoleLoggerProvider(config));
        return loggerFactory;
    }
    public static ILoggerFactory AddColorConsoleLogger(
                                      this ILoggerFactory loggerFactory)
    {
        var config = new ColorConsoleLoggerConfiguration();
        return loggerFactory.AddColorConsoleLogger(config);
    }
    public static ILoggerFactory AddColorConsoleLogger(
                                    this ILoggerFactory loggerFactory, 
                                    Action<ColorConsoleLoggerConfiguration> configure)
    {
        var config = new ColorConsoleLoggerConfiguration();
        configure(config);
        return loggerFactory.AddColorConsoleLogger(config);
    }
}

其他资源Additional resources

作者:Tom DykstraSteve SmithBy Tom Dykstra and Steve Smith

.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。.NET Core supports a logging API that works with a variety of built-in and third-party logging providers. 本文介绍了如何将日志记录 API 与内置提供程序一起使用。This article shows how to use the logging API with built-in providers.

查看或下载示例代码如何下载View or download sample code (how to download)

添加提供程序Add providers

日志记录提供程序会显示或存储日志。A logging provider displays or stores logs. 例如,控制台提供程序在控制台上显示日志,Azure Application Insights 提供程序会将这些日志存储在 Azure Application Insights 中。For example, the Console provider displays logs on the console, and the Azure Application Insights provider stores them in Azure Application Insights. 可通过添加多个提供程序将日志发送到多个目标。Logs can be sent to multiple destinations by adding multiple providers.

要添加提供程序,请在 Program.cs 中调用提供程序的 Add{provider name} 扩展方法 :To add a provider, call the provider's Add{provider name} extension method in Program.cs:

public static void Main(string[] args)
{
    var webHost = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;
            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
                      optional: true, reloadOnChange: true);
            config.AddEnvironmentVariables();
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
            // Requires `using Microsoft.Extensions.Logging;`
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
        })
        .UseStartup<Startup>()
        .Build();

    webHost.Run();
}

前面的代码需要引用 Microsoft.Extensions.LoggingMicrosoft.Extensions.ConfigurationThe preceding code requires references to Microsoft.Extensions.Logging and Microsoft.Extensions.Configuration.

默认项目模板调用 CreateDefaultBuilder,该操作将添加以下日志记录提供程序:The default project template calls CreateDefaultBuilder, which adds the following logging providers:

  • 控制台Console
  • 调试Debug
  • EventSource(从 ASP.NET Core 2.2 开始)EventSource (starting in ASP.NET Core 2.2)
public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

如果使用 CreateDefaultBuilder,则可自行选择提供程序来替换默认提供程序。If you use CreateDefaultBuilder, you can replace the default providers with your own choices. 调用 ClearProviders,然后添加所需的提供程序。Call ClearProviders, and add the providers you want.

public static void Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    var todoRepository = host.Services.GetRequiredService<ITodoRepository>();
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Feed the dog" });
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Walk the dog" });

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Seeded the database.");

    host.Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        });

详细了解内置日志记录提供程序,以及本文稍后部分介绍的第三方日志记录提供程序Learn more about built-in logging providers and third-party logging providers later in the article.

创建日志Create logs

若要创建日志,请使用 ILogger<TCategoryName> 对象。To create logs, use an ILogger<TCategoryName> object. 在 Web 应用或托管服务中,由依赖关系注入 (DI) 获取 ILoggerIn a web app or hosted service, get an ILogger from dependency injection (DI). 在非主机控制台应用中,使用 LoggerFactory 来创建 ILoggerIn non-host console apps, use the LoggerFactory to create an ILogger.

下面的 ASP.NET Core 示例创建了一个以 TodoApiSample.Pages.AboutModel 为类别的记录器。The following ASP.NET Core example creates a logger with TodoApiSample.Pages.AboutModel as the category. 日志“类别”是与每个日志关联的字符串 。The log category is a string that is associated with each log. DI 提供的 ILogger<T> 实例创建日志,该日志以类型 T 的完全限定名称为类别。The ILogger<T> instance provided by DI creates logs that have the fully qualified name of type T as the category.

public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

在下面的 ASP.NET Core 和控制台应用示例中,记录器用于创建以 Information 为级别的日志。In the following ASP.NET Core and console app examples, the logger is used to create logs with Information as the level. 日志“级别”代表所记录事件的严重程度 。The Log level indicates the severity of the logged event.

public void OnGet()
{
    Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
    _logger.LogInformation("Message displayed: {Message}", Message);
}

本文稍后部分将更详细地介绍级别类别Levels and categories are explained in more detail later in this article.

启动时创建日志Create logs in Startup

要将日志写入 Startup 类,构造函数签名需包含 ILogger 参数:To write logs in the Startup class, include an ILogger parameter in the constructor signature:

public class Startup
{
    private readonly ILogger _logger;

    public Startup(IConfiguration configuration, ILogger<Startup> logger)
    {
        Configuration = configuration;
        _logger = logger;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        // Add our repository type
        services.AddSingleton<ITodoRepository, TodoRepository>();
        _logger.LogInformation("Added TodoRepository to services");
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            _logger.LogInformation("In Development environment");
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseMvc();
    }
}

在 Program 类中创建日志Create logs in the Program class

要将日志写入 Program 类,请从 DI 获取 ILogger 实例:To write logs in the Program class, get an ILogger instance from DI:

public static void Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    var todoRepository = host.Services.GetRequiredService<ITodoRepository>();
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Feed the dog" });
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Walk the dog" });

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Seeded the database.");

    host.Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        });

不直接支持在主机构造期间进行日志记录。Logging during host construction isn't directly supported. 但是,可以使用单独的记录器。However, a separate logger can be used. 在以下示例中,Serilog 记录器用于登录 CreateWebHostBuilderIn the following example, a Serilog logger is used to log in CreateWebHostBuilder. AddSerilog 使用 Log.Logger 中指定的静态配置:AddSerilog uses the static configuration specified in Log.Logger:

using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return WebHost.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddMvc();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {
                    logging.AddSerilog();
                })
                .UseStartup<Startup>();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

没有异步记录器方法No asynchronous logger methods

日志记录应该会很快,不值得牺牲性能来使用异步代码。Logging should be so fast that it isn't worth the performance cost of asynchronous code. 如果你的日志数据存储很慢,请不要直接写入它。If your logging data store is slow, don't write to it directly. 首先考虑将日志消息写入快速存储,稍后再将其变为慢速存储。Consider writing the log messages to a fast store initially, then move them to the slow store later. 例如,如果你要记录到 SQL Server,你可能不想直接在 Log 方法中记录,因为 Log 方法是同步的。For example, if you're logging to SQL Server, you don't want to do that directly in a Log method, since the Log methods are synchronous. 相反,你会将日志消息同步添加到内存中的队列,并让后台辅助线程从队列中拉出消息,以完成将数据推送到 SQL Server 的异步工作。Instead, synchronously add log messages to an in-memory queue and have a background worker pull the messages out of the queue to do the asynchronous work of pushing data to SQL Server. 有关详细信息,请参阅 GitHub 问题。For more information, see this GitHub issue.

ConfigurationConfiguration

日志记录提供程序配置由一个或多个配置提供程序提供:Logging provider configuration is provided by one or more configuration providers:

  • 文件格式(INI、JSON 和 XML)。File formats (INI, JSON, and XML).
  • 命令行参数。Command-line arguments.
  • 环境变量。Environment variables.
  • 内存中的 .NET 对象。In-memory .NET objects.
  • 未加密的机密管理器存储。The unencrypted Secret Manager storage.
  • 加密的用户存储,如 Azure Key VaultAn encrypted user store, such as Azure Key Vault.
  • (已安装或已创建的)自定义提供程序。Custom providers (installed or created).

例如,日志记录配置通常由应用设置文件的 Logging 部分提供。For example, logging configuration is commonly provided by the Logging section of app settings files. 以下示例显示了典型 appsettings.Development.json 文件的内容:The following example shows the contents of a typical appsettings.Development.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "Console":
    {
      "IncludeScopes": true
    }
  }
}

Logging 属性可具有 LogLevel 和日志提供程序属性(显示控制台)。The Logging property can have LogLevel and log provider properties (Console is shown).

Logging 下的 LogLevel 属性指定了用于记录所选类别的最低级别The LogLevel property under Logging specifies the minimum level to log for selected categories. 在本例中,SystemMicrosoft 类别在 Information 级别记录,其他均在 Debug 级别记录。In the example, System and Microsoft categories log at Information level, and all others log at Debug level.

Logging 下的其他属性均指定了日志记录提供程序。Other properties under Logging specify logging providers. 本示例针对控制台提供程序。The example is for the Console provider. 如果提供程序支持日志作用域,则 IncludeScopes 将指示是否启用这些域。If a provider supports log scopes, IncludeScopes indicates whether they're enabled. 提供程序属性(例如本例的 Console)也可指定 LogLevel 属性。A provider property (such as Console in the example) may also specify a LogLevel property. 提供程序下的 LogLevel 指定了该提供程序记录的级别。LogLevel under a provider specifies levels to log for that provider.

如果在 Logging.{providername}.LogLevel 中指定了级别,则这些级别将重写 Logging.LogLevel 中设置的所有内容。If levels are specified in Logging.{providername}.LogLevel, they override anything set in Logging.LogLevel. 例如,考虑以下 JSON:For example, consider the following JSON:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

在前面的 JSON 中,Console 提供程序设置将替代前面的(默认)日志级别。In the preceding JSON, the Console provider settings overrides the preceding (default) log level.

不可使用日志记录 API 在应用运行时更改日志记录。The Logging API doesn't include a scenario to change log levels while an app is running. 但是,一些配置提供程序可重新加载配置,这将对日志记录配置立即产生影响。However, some configuration providers are capable of reloading configuration, which takes immediate effect on logging configuration. 例如,文件配置提供程序会默认重新加载日志记录配置,该程序由 CreateDefaultBuilder 添加用来读取设置文件。For example, the File Configuration Provider, which is added by CreateDefaultBuilder to read settings files, reloads logging configuration by default. 如果在应用运行时在代码中更改了配置,则该应用可调用 IConfigurationRoot.Reload 来更新应用的日志记录配置。If configuration is changed in code while an app is running, the app can call IConfigurationRoot.Reload to update the app's logging configuration.

若要了解如何实现配置提供程序,请参阅 ASP.NET Core 中的配置For information on implementing configuration providers, see ASP.NET Core 中的配置.

日志记录输出示例Sample logging output

使用上一部分中显示的示例代码从命令行运行应用时,将在控制台中看到日志。With the sample code shown in the preceding section, logs appear in the console when the app is run from the command line. 以下是控制台输出示例:Here's an example of console output:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/api/todo/0
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
      Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
      GetById(0) NOT FOUND
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 42.9286ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 148.889ms 404

通过向 http://localhost:5000/api/todo/0 处的示例应用发出 HTTP Get 请求来生成前述日志。The preceding logs were generated by making an HTTP Get request to the sample app at http://localhost:5000/api/todo/0.

在 Visual Studio 中运行示例应用时,“调试”窗口中将显示如下日志:Here's an example of the same logs as they appear in the Debug window when you run the sample app in Visual Studio:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:53104/api/todo/0  
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
TodoApi.Controllers.TodoController:Information: Getting item 0
TodoApi.Controllers.TodoController:Warning: GetById(0) NOT FOUND
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 404
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 152.5657ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 316.3195ms 404

由上一部分所示的 ILogger 调用创建的日志以“TodoApi”开头。The logs that are created by the ILogger calls shown in the preceding section begin with "TodoApi". 以“Microsoft”类别开头的日志来自 ASP.NET Core 框架代码。The logs that begin with "Microsoft" categories are from ASP.NET Core framework code. ASP.NET Core 和应用程序代码使用相同的日志记录 API 和提供程序。ASP.NET Core and application code are using the same logging API and providers.

本文余下部分将介绍有关日志记录的某些详细信息及选项。The remainder of this article explains some details and options for logging.

NuGet 包NuGet packages

ILoggerILoggerFactory 接口位于 Microsoft.Extensions.Logging.Abstractions 中,其默认实现位于 Microsoft.Extensions.Logging 中。The ILogger and ILoggerFactory interfaces are in Microsoft.Extensions.Logging.Abstractions, and default implementations for them are in Microsoft.Extensions.Logging.

日志类别Log category

创建 ILogger 对象后,将为其指定“类别” 。When an ILogger object is created, a category is specified for it. 该类别包含在由此 ILogger 实例创建的每条日志消息中。That category is included with each log message created by that instance of ILogger. 类别可以是任何字符串,但约定需使用类名,例如“TodoApi.Controllers.TodoController”。The category may be any string, but the convention is to use the class name, such as "TodoApi.Controllers.TodoController".

使用 ILogger<T> 获取一个 ILogger 实例,该实例使用 T 的完全限定类型名称作为类别:Use ILogger<T> to get an ILogger instance that uses the fully qualified type name of T as the category:

public class TodoController : Controller
{
    private readonly ITodoRepository _todoRepository;
    private readonly ILogger _logger;

    public TodoController(ITodoRepository todoRepository,
        ILogger<TodoController> logger)
    {
        _todoRepository = todoRepository;
        _logger = logger;
    }

要显式指定类别,请调用 ILoggerFactory.CreateLoggerTo explicitly specify the category, call ILoggerFactory.CreateLogger:

public class TodoController : Controller
{
    private readonly ITodoRepository _todoRepository;
    private readonly ILogger _logger;

    public TodoController(ITodoRepository todoRepository,
        ILoggerFactory logger)
    {
        _todoRepository = todoRepository;
        _logger = logger.CreateLogger("TodoApiSample.Controllers.TodoController");
    }

ILogger<T> 相当于使用 T 的完全限定类型名称来调用 CreateLoggerILogger<T> is equivalent to calling CreateLogger with the fully qualified type name of T.

日志级别Log level

每个日志都指定了一个 LogLevel 值。Every log specifies a LogLevel value. 日志级别指示严重性或重要程度。The log level indicates the severity or importance. 例如,可在方法正常结束时写入 Information 日志,在方法返回“404 找不到”状态代码时写入 Warning 日志 。For example, you might write an Information log when a method ends normally and a Warning log when a method returns a 404 Not Found status code.

下面的代码会创建 InformationWarning 日志:The following code creates Information and Warning logs:

public IActionResult GetById(string id)
{
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
    {
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    }
    return new ObjectResult(item);
}

在前面的代码中,MyLogEvents.GetItemMyLogEvents.GetItemNotFound 参数是日志事件 IDIn the preceding code, the MyLogEvents.GetItem and MyLogEvents.GetItemNotFound parameters are the Log event ID. 第二个参数是消息模板,其中的占位符用于填写剩余方法形参提供的实参值。The second parameter is a message template with placeholders for argument values provided by the remaining method parameters. 本文的日志消息模板部分将介绍方法参数。The method parameters are explained in the Log message template section in this article.

在方法名称中包含级别的日志方法(例如 LogInformationLogWarning)是 ILogger 的扩展方法Log methods that include the level in the method name (for example, LogInformation and LogWarning) are extension methods for ILogger. 这些方法会调用可接受 LogLevel 参数的 Log 方法。These methods call a Log method that takes a LogLevel parameter. 可直接调用 Log 方法而不调用其中某个扩展方法,但语法相对复杂。You can call the Log method directly rather than one of these extension methods, but the syntax is relatively complicated. 有关详细信息,请参阅 ILogger记录器扩展源代码For more information, see ILogger and the logger extensions source code.

ASP.NET Core 定义了以下日志级别(按严重性从低到高排列)。ASP.NET Core defines the following log levels, ordered here from lowest to highest severity.

  • 跟踪 = 0Trace = 0

    有关通常仅用于调试的信息。For information that's typically valuable only for debugging. 这些消息可能包含敏感应用程序数据,因此不得在生产环境中启用它们。These messages may contain sensitive application data and so shouldn't be enabled in a production environment. 默认情况下禁用。Disabled by default.

  • 调试 = 1Debug = 1

    有关在开发和调试中可能有用的信息。For information that may be useful in development and debugging. 示例:Entering method Configure with flag set to true. 由于日志数量过多,因此仅当执行故障排除时,才在生产中启用 Debug 级别日志。Example: Entering method Configure with flag set to true. Enable Debug level logs in production only when troubleshooting, due to the high volume of logs.

  • 信息 = 2Information = 2

    用于跟踪应用的常规流。For tracking the general flow of the app. 这些日志通常有长期价值。These logs typically have some long-term value. 示例:Request received for path /api/todoExample: Request received for path /api/todo

  • 警告 = 3Warning = 3

    表示应用流中的异常或意外事件。For abnormal or unexpected events in the app flow. 可能包括不会中断应用运行但仍需调查的错误或其他条件。These may include errors or other conditions that don't cause the app to stop but might need to be investigated. Warning 日志级别常用于已处理的异常。Handled exceptions are a common place to use the Warning log level. 示例:FileNotFoundException for file quotes.txt.Example: FileNotFoundException for file quotes.txt.

  • 错误 = 4Error = 4

    表示无法处理的错误和异常。For errors and exceptions that cannot be handled. 这些消息指示的是当前活动或操作(例如当前 HTTP 请求)中的失败,而不是整个应用中的失败。These messages indicate a failure in the current activity or operation (such as the current HTTP request), not an app-wide failure. 日志消息示例:Cannot insert record due to duplicate key violation.Example log message: Cannot insert record due to duplicate key violation.

  • 严重 = 5Critical = 5

    需要立即关注的失败。For failures that require immediate attention. 例如数据丢失、磁盘空间不足。Examples: data loss scenarios, out of disk space.

使用日志级别控制写入到特定存储介质或显示窗口的日志输出量。Use the log level to control how much log output is written to a particular storage medium or display window. 例如:For example:

  • 生产中:In production:
    • 如果通过 Information 级别在 Trace 处记录,则会生成大量详细的日志消息。Logging at the Trace through Information levels produces a high-volume of detailed log messages. 为控制成本且不超过数据存储限制,请通过 Information 级别消息将 Trace 记录到容量大、成本低的数据存储中。To control costs and not exceed data storage limits, log Trace through Information level messages to a high-volume, low-cost data store.
    • 如果通过 Critical 级别在 Warning 处记录,通常生成的日志消息更少且更小。Logging at Warning through Critical levels typically produces fewer, smaller log messages. 因此,成本和存储限制通常不是问题,而这使得在选择数据信息时更为灵活。Therefore, costs and storage limits usually aren't a concern, which results in greater flexibility of data store choice.
  • 在开发过程中:During development:
    • 通过 Critical 消息将 Warning 记录到控制台。Log Warning through Critical messages to the console.
    • 在疑难解答时通过 Information 消息添加 TraceAdd Trace through Information messages when troubleshooting.

本文稍后的日志筛选部分介绍如何控制提供程序处理的日志级别。The Log filtering section later in this article explains how to control which log levels a provider handles.

ASP.NET Core 为框架事件写入日志。ASP.NET Core writes logs for framework events. 本文前面部分提供的日志示例排除了低于 Information 级别的日志,因此未创建 DebugTrace 级别日志。The log examples earlier in this article excluded logs below Information level, so no Debug or Trace level logs were created. 以下示例介绍了通过运行配置为显示 Debug 日志的示例应用而生成的控制台日志:Here's an example of console logs produced by running the sample app configured to show Debug logs:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:62555/api/todo/0
dbug: Microsoft.AspNetCore.Routing.Tree.TreeRouter[1]
      Request successfully matched the route with name 'GetTodo' and template 'api/Todo/{id}'.
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'TodoApi.Controllers.TodoController.Update (TodoApi)' with id '089d59b6-92ec-472d-b552-cc613dfd625d' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'TodoApi.Controllers.TodoController.Delete (TodoApi)' with id 'f3476abe-4bd9-4ad3-9261-3ead09607366' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action TodoApi.Controllers.TodoController.GetById (TodoApi)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
      Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
      GetById(0) NOT FOUND
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action method TodoApi.Controllers.TodoController.GetById (TodoApi), returned result Microsoft.AspNetCore.Mvc.NotFoundResult.
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 0.8788ms
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
      Connection id "0HL6L7NEFF2QD" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 2.7286ms 404

日志事件 IDLog event ID

每个日志都可指定一个事件 ID 。Each log can specify an event ID. 该示例应用通过使用本地定义的 LoggingEvents 类来执行此操作:The sample app does this by using a locally defined LoggingEvents class:

public IActionResult GetById(string id)
{
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
    {
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    }
    return new ObjectResult(item);
}
public class LoggingEvents
{
    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 GetItemNotFound = 4000;
    public const int UpdateItemNotFound = 4001;
}

事件 ID 与一组事件相关联。An event ID associates a set of events. 例如,与在页面上显示项列表相关的所有日志可能是 1001。For example, all logs related to displaying a list of items on a page might be 1001.

日志记录提供程序可将事件 ID 存储在 ID 字段中,存储在日志记录消息中,或者不进行存储。The logging provider may store the event ID in an ID field, in the logging message, or not at all. 调试提供程序不显示事件 ID。The Debug provider doesn't show event IDs. 控制台提供程序在类别后的括号中显示事件 ID:The console provider shows event IDs in brackets after the category:

info: TodoApi.Controllers.TodoController[1002]
      Getting item invalidid
warn: TodoApi.Controllers.TodoController[4000]
      GetById(invalidid) NOT FOUND

日志消息模板Log message template

每个日志都会指定一个消息模板。Each log specifies a message template. 消息模板可包含要填写参数的占位符。The message template can contain placeholders for which arguments are provided. 请在占位符中使用名称而不是数字。Use names for the placeholders, not numbers.

public IActionResult GetById(string id)
{
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
    {
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    }
    return new ObjectResult(item);
}

占位符的顺序(而非其名称)决定了为其提供值的参数。The order of placeholders, not their names, determines which parameters are used to provide their values. 在以下代码中,请注意消息模板中的参数名称未按顺序排列:In the following code, notice that the parameter names are out of sequence in the message template:

string p1 = "parm1";
string p2 = "parm2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);

此代码创建了一个参数值按顺序排列的日志消息:This code creates a log message with the parameter values in sequence:

Parameter values: parm1, parm2

日志记录框架按此方式工作,这样日志记录提供程序即可实现语义日志记录,也称为结构化日志记录The logging framework works this way so that logging providers can implement semantic logging, also known as structured logging. 参数本身会传递给日志记录系统,而不仅仅是格式化的消息模板。The arguments themselves are passed to the logging system, not just the formatted message template. 通过此信息,日志记录提供程序能够将参数值存储为字段。This information enables logging providers to store the parameter values as fields. 例如,假设记录器方法调用如下所示:For example, suppose logger method calls look like this:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

如果要将日志发送到 Azure 表存储,则每个 Azure 表实体都可具有 IDRequestTime 属性,这简化了对日志数据的查询。If you're sending the logs to Azure Table Storage, each Azure Table entity can have ID and RequestTime properties, which simplifies queries on log data. 无需分析文本消息的超时,查询即可找到特定 RequestTime 范围内的全部日志。A query can find all logs within a particular RequestTime range without parsing the time out of the text message.

日志记录异常Logging exceptions

记录器方法有可传入异常的重载,如下方示例所示:The logger methods have overloads that let you pass in an exception, as in the following example:

catch (Exception ex)
{
    _logger.LogWarning(LoggingEvents.GetItemNotFound, ex, "GetById({Id}) NOT FOUND", id);
    return NotFound();
}
return new ObjectResult(item);

不同的提供程序处理异常信息的方式不同。Different providers handle the exception information in different ways. 以下是上示代码的调试提供程序输出示例。Here's an example of Debug provider output from the code shown above.

TodoApiSample.Controllers.TodoController: Warning: GetById(55) NOT FOUND

System.Exception: Item not found exception.
   at TodoApiSample.Controllers.TodoController.GetById(String id) in C:\TodoApiSample\Controllers\TodoController.cs:line 226

日志筛选Log filtering

可为特定或所有提供程序和类别指定最低日志级别。You can specify a minimum log level for a specific provider and category or for all providers or all categories. 最低级别以下的日志不会传递给该提供程序,因此不会显示或存储它们。Any logs below the minimum level aren't passed to that provider, so they don't get displayed or stored.

要禁止显示所有日志,可将 LogLevel.None 指定为最低日志级别。To suppress all logs, specify LogLevel.None as the minimum log level. LogLevel.None 的整数值为 6,它大于 LogLevel.Critical (5)。The integer value of LogLevel.None is 6, which is higher than LogLevel.Critical (5).

在配置中创建筛选规则Create filter rules in configuration

项目模板代码调用 CreateDefaultBuilder 来为 Console、Debug 和 EventSource(ASP.NET Core 2.2 或更高版本)提供程序设置日志记录。The project template code calls CreateDefaultBuilder to set up logging for the Console, Debug, and EventSource (ASP.NET Core 2.2 or later) providers. 正如本文前面部分所述,CreateDefaultBuilder 方法设置日志记录以在 Logging 部分查找配置。The CreateDefaultBuilder method sets up logging to look for configuration in a Logging section, as explained earlier in this article.

配置数据按提供程序和类别指定最低日志级别,如下方示例所示:The configuration data specifies minimum log levels by provider and category, as in the following example:

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

此 JSON 将创建 6 条筛选规则:1 条用于调试提供程序, 4 条用于控制台提供程序, 1 条用于所有提供程序。This JSON creates six filter rules: one for the Debug provider, four for the Console provider, and one for all providers. 创建 ILogger 对象时,为每个提供程序选择一个规则。A single rule is chosen for each provider when an ILogger object is created.

代码中的筛选规则Filter rules in code

下面的示例演示了如何在代码中注册筛选规则:The following example shows how to register filter rules in code:

WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureLogging(logging =>
        logging.AddFilter("System", LogLevel.Debug)
               .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Trace));

第二个 AddFilter 使用类型名称来指定调试提供程序。The second AddFilter specifies the Debug provider by using its type name. 第一个 AddFilter 应用于全部提供程序,因为它未指定提供程序类型。The first AddFilter applies to all providers because it doesn't specify a provider type.

如何应用筛选规则How filtering rules are applied

先前示例中显示的配置数据和 AddFilter 代码会创建下表所示的规则。The configuration data and the AddFilter code shown in the preceding examples create the rules shown in the following table. 前六条由配置示例创建,后两条由代码示例创建。The first six come from the configuration example and the last two come from the code example.

数字Number 提供程序Provider 类别的开头为...Categories that begin with ... 最低日志级别Minimum log level
11 调试Debug 全部类别All categories 信息Information
22 控制台Console Microsoft.AspNetCore.Mvc.Razor.InternalMicrosoft.AspNetCore.Mvc.Razor.Internal 警告Warning
33 控制台Console Microsoft.AspNetCore.Mvc.Razor.RazorMicrosoft.AspNetCore.Mvc.Razor.Razor 调试Debug
44 控制台Console Microsoft.AspNetCore.Mvc.RazorMicrosoft.AspNetCore.Mvc.Razor 错误Error
55 控制台Console 全部类别All categories 信息Information
66 全部提供程序All providers 全部类别All categories 调试Debug
77 全部提供程序All providers SystemSystem 调试Debug
88 调试Debug MicrosoftMicrosoft 跟踪Trace

创建 ILogger 对象时,ILoggerFactory 对象将根据提供程序选择一条规则,将其应用于该记录器。When an ILogger object is created, the ILoggerFactory object selects a single rule per provider to apply to that logger. 将按所选规则筛选 ILogger 实例写入的所有消息。All messages written by an ILogger instance are filtered based on the selected rules. 从可用规则中为每个提供程序和类别对选择最具体的规则。The most specific rule possible for each provider and category pair is selected from the available rules.

在为给定的类别创建 ILogger 时,以下算法将用于每个提供程序:The following algorithm is used for each provider when an ILogger is created for a given category:

  • 选择匹配提供程序或其别名的所有规则。Select all rules that match the provider or its alias. 如果找不到任何匹配项,则选择提供程序为空的所有规则。If no match is found, select all rules with an empty provider.
  • 根据上一步的结果,选择具有最长匹配类别前缀的规则。From the result of the preceding step, select rules with longest matching category prefix. 如果找不到任何匹配项,则选择未指定类别的所有规则。If no match is found, select all rules that don't specify a category.
  • 如果选择了多条规则,则采用最后一条 。If multiple rules are selected, take the last one.
  • 如果未选择任何规则,则使用 MinimumLevelIf no rules are selected, use MinimumLevel.

使用前面的规则列表,假设你为类别“Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine”创建 ILogger 对象:With the preceding list of rules, suppose you create an ILogger object for category "Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine":

  • 对于调试提供程序,规则 1、6 和 8 适用。For the Debug provider, rules 1, 6, and 8 apply. 规则 8 最为具体,因此选择了它。Rule 8 is most specific, so that's the one selected.
  • 对于控制台提供程序,符合的有规则 3、规则 4、规则 5 和规则 6。For the Console provider, rules 3, 4, 5, and 6 apply. 规则 3 最为具体。Rule 3 is most specific.

生成的 ILogger 实例将 Trace 级别及更高级别的日志发送到调试提供程序。The resulting ILogger instance sends logs of Trace level and above to the Debug provider. Debug 级别及更高级别的日志会发送到控制台提供程序。Logs of Debug level and above are sent to the Console provider.

提供程序别名Provider aliases

每个提供程序都定义了一个别名;可在配置中使用该别名来代替完全限定的类型名称 。Each provider defines an alias that can be used in configuration in place of the fully qualified type name. 对于内置提供程序,请使用以下别名:For the built-in providers, use the following aliases:

  • 控制台Console
  • 调试Debug
  • EventSourceEventSource
  • EventLogEventLog
  • TraceSourceTraceSource
  • AzureAppServicesFileAzureAppServicesFile
  • AzureAppServicesBlobAzureAppServicesBlob
  • ApplicationInsightsApplicationInsights

默认最低级别Default minimum level

仅当配置或代码中的规则对给定提供程序和类别都不适用时,最低级别设置才会生效。There's a minimum level setting that takes effect only if no rules from configuration or code apply for a given provider and category. 下面的示例演示如何设置最低级别:The following example shows how to set the minimum level:

WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning));

如果没有明确设置最低级别,则默认值为 Information,它表示 TraceDebug 日志将被忽略。If you don't explicitly set the minimum level, the default value is Information, which means that Trace and Debug logs are ignored.

筛选器函数Filter functions

对配置或代码没有向其分配规则的所有提供程序和类别调用筛选器函数。A filter function is invoked for all providers and categories that don't have rules assigned to them by configuration or code. 函数中的代码可访问提供程序类型、类别和日志级别。Code in the function has access to the provider type, category, and log level. 例如:For example:

WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureLogging(logBuilder =>
    {
        logBuilder.AddFilter((provider, category, logLevel) =>
        {
            if (provider == "Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider" &&
                category == "TodoApiSample.Controllers.TodoController")
            {
                return false;
            }
            return true;
        });
    });

系统类别和级别System categories and levels

下面是 ASP.NET Core 和 Entity Framework Core 使用的一些类别,备注中说明了可从这些类别获取的具体日志:Here are some categories used by ASP.NET Core and Entity Framework Core, with notes about what logs to expect from them:

类别Category 说明Notes
Microsoft.AspNetCoreMicrosoft.AspNetCore 常规 ASP.NET Core 诊断。General ASP.NET Core diagnostics.
Microsoft.AspNetCore.DataProtectionMicrosoft.AspNetCore.DataProtection 考虑、找到并使用了哪些密钥。Which keys were considered, found, and used.
Microsoft.AspNetCore.HostFilteringMicrosoft.AspNetCore.HostFiltering 所允许的主机。Hosts allowed.
Microsoft.AspNetCore.HostingMicrosoft.AspNetCore.Hosting HTTP 请求完成的时间和启动时间。How long HTTP requests took to complete and what time they started. 加载了哪些承载启动程序集。Which hosting startup assemblies were loaded.
Microsoft.AspNetCore.MvcMicrosoft.AspNetCore.Mvc MVC 和 Razor 诊断。MVC and Razor diagnostics. 模型绑定、筛选器执行、视图编译和操作选择。Model binding, filter execution, view compilation, action selection.
Microsoft.AspNetCore.RoutingMicrosoft.AspNetCore.Routing 路由匹配信息。Route matching information.
Microsoft.AspNetCore.ServerMicrosoft.AspNetCore.Server 连接启动、停止和保持活动响应。Connection start, stop, and keep alive responses. HTTP 证书信息。HTTPS certificate information.
Microsoft.AspNetCore.StaticFilesMicrosoft.AspNetCore.StaticFiles 提供的文件。Files served.
Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore 常规 Entity Framework Core 诊断。General Entity Framework Core diagnostics. 数据库活动和配置、更改检测、迁移。Database activity and configuration, change detection, migrations.

日志作用域Log scopes

“作用域”可对一组逻辑操作分组 。A scope can group a set of logical operations. 此分组可用于将相同的数据附加到作为集合的一部分而创建的每个日志。This grouping can be used to attach the same data to each log that's created as part of a set. 例如,在处理事务期间创建的每个日志都可包括事务 ID。For example, every log created as part of processing a transaction can include the transaction ID.

范围是由 BeginScope 方法返回的 IDisposable 类型,持续至释放为止。A scope is an IDisposable type that's returned by the BeginScope method and lasts until it's disposed. 要使用作用域,请在 using 块中包装记录器调用:Use a scope by wrapping logger calls in a using block:

public IActionResult GetById(string id)
{
    TodoItem item;
    using (_logger.BeginScope("Message attached to logs created in the using block"))
    {
        _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
        item = _todoRepository.Find(id);
        if (item == null)
        {
            _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
            return NotFound();
        }
    }
    return new ObjectResult(item);
}

下列代码为控制台提供程序启用作用域:The following code enables scopes for the console provider:

Program.cs :Program.cs:

.ConfigureLogging((hostingContext, logging) =>
{
    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
    logging.AddConsole(options => options.IncludeScopes = true);
    logging.AddDebug();
})

备注

要启用基于作用域的日志记录,必须先配置 IncludeScopes 控制台记录器选项。Configuring the IncludeScopes console logger option is required to enable scope-based logging.

若要了解关配置,请参阅配置部分。For information on configuration, see the Configuration section.

每条日志消息都包含作用域内的信息:Each log message includes the scoped information:

info: TodoApiSample.Controllers.TodoController[1002]
      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApiSample.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
      Getting item 0
warn: TodoApiSample.Controllers.TodoController[4000]
      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApiSample.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
      GetById(0) NOT FOUND

内置日志记录提供程序Built-in logging providers

ASP.NET Core 提供以下提供程序:ASP.NET Core ships the following providers:

要通过 ASP.NET Core 模块了解 stdout 和调试日志记录,请参阅 对 Azure 应用服务和 IIS 上的 ASP.NET Core 进行故障排除ASP.NET Core 模块For information on stdout and debug logging with the ASP.NET Core Module, see 对 Azure 应用服务和 IIS 上的 ASP.NET Core 进行故障排除 and ASP.NET Core 模块.

控制台提供程序Console provider

Microsoft.Extensions.Logging.Console 提供程序包向控制台发送日志输出。The Microsoft.Extensions.Logging.Console provider package sends log output to the console.

logging.AddConsole();

要查看控制台日志记录输出,请在项目文件夹中打开命令提示符并运行以下命令:To see console logging output, open a command prompt in the project folder and run the following command:

dotnet run

调试提供程序Debug provider

Microsoft.Extensions.Logging.Debug 提供程序包使用 System.Diagnostics.Debug 类(Debug.WriteLine 方法调用)来写入日志输出。The Microsoft.Extensions.Logging.Debug provider package writes log output by using the System.Diagnostics.Debug class (Debug.WriteLine method calls).

在 Linux 中,此提供程序将日志写入 /var/log/message 。On Linux, this provider writes logs to /var/log/message.

logging.AddDebug();

事件源提供程序Event Source provider

Microsoft.Extensions.Logging.EventSource 提供程序包会使用名称 Microsoft-Extensions-Logging 跨平台写入事件源。The Microsoft.Extensions.Logging.EventSource provider package writes to an Event Source cross-platform with the name Microsoft-Extensions-Logging. 在 Windows 上,提供程序使用的是 ETWOn Windows, the provider uses ETW.

logging.AddEventSourceLogger();

在调用 CreateDefaultBuilder 来生成主机时,会自动添加事件源提供程序。The Event Source provider is added automatically when CreateDefaultBuilder is called to build the host.

使用 PerfView 实用工具收集和查看日志。Use the PerfView utility to collect and view logs. 虽然其他工具也可以查看 ETW 日志,但在处理由 ASP.NET Core 发出的 ETW 事件时,使用 PerfView 能获得最佳体验。There are other tools for viewing ETW logs, but PerfView provides the best experience for working with the ETW events emitted by ASP.NET Core.

要将 PerfView 配置为收集此提供程序记录的事件,请向 Additional Providers 列表添加字符串 *Microsoft-Extensions-LoggingTo configure PerfView for collecting events logged by this provider, add the string *Microsoft-Extensions-Logging to the Additional Providers list. (请勿遗漏字符串起始处的星号。)(Don't miss the asterisk at the start of the string.)

其他 Perfview 提供程序

Windows EventLog 提供程序Windows EventLog provider

Microsoft.Extensions.Logging.EventLog 提供程序包向 Windows 事件日志发送日志输出。The Microsoft.Extensions.Logging.EventLog provider package sends log output to the Windows Event Log.

logging.AddEventLog();

AddEventLog 重载允许传入 EventLogSettingsAddEventLog overloads let you pass in EventLogSettings. 如果为 null 或未指定,则使用以下默认设置:If null or not specified, the following default settings are used:

  • LogName:“Application”LogName: "Application"
  • SourceName:“.NET Runtime”SourceName: ".NET Runtime"
  • MachineName:使用本地计算机名称。MachineName: The local machine name is used.

警告等级和更高等级记录事件。Events are logged for Warning level and higher. 以下示例将事件日志的默认日志级别设置为 LogLevel.InformationThe following example sets the Event Log default log level to LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

TraceSource 提供程序TraceSource provider

Microsoft.Extensions.Logging.TraceSource 提供程序包使用 TraceSource 库和提供程序。The Microsoft.Extensions.Logging.TraceSource provider package uses the TraceSource libraries and providers.

logging.AddTraceSource(sourceSwitchName);

AddTraceSource 重载 允许传入资源开关和跟踪侦听器。AddTraceSource overloads let you pass in a source switch and a trace listener.

要使用此提供程序,应用必须在 .NET Framework(而非 .NET Core)上运行。To use this provider, an app has to run on the .NET Framework (rather than .NET Core). 提供程序可将消息路由到多个侦听器,例如示例应用中使用的 TextWriterTraceListenerThe provider can route messages to a variety of listeners, such as the TextWriterTraceListener used in the sample app.

Azure 应用服务提供程序Azure App Service provider

Microsoft.Extensions.Logging.AzureAppServices 提供程序包将日志写入 Azure App Service 应用的文件系统,以及 Azure 存储帐户中的 blob 存储The Microsoft.Extensions.Logging.AzureAppServices provider package writes logs to text files in an Azure App Service app's file system and to blob storage in an Azure Storage account.

logging.AddAzureWebAppDiagnostics();

Microsoft.AspNetCore.App 元包中不包括此提供程序包。The provider package isn't included in the Microsoft.AspNetCore.App metapackage. 如果面向 .NET Framework 或引用 Microsoft.AspNetCore.App 元包,请向项目添加提供程序包。When targeting .NET Framework or referencing the Microsoft.AspNetCore.App metapackage, add the provider package to the project.

AddAzureWebAppDiagnostics 重载允许传入 AzureAppServicesDiagnosticsSettingsAn AddAzureWebAppDiagnostics overload lets you pass in AzureAppServicesDiagnosticsSettings. 设置对象可以覆盖默认设置,例如日志记录输出模板、blob 名称和文件大小限制。The settings object can override default settings, such as the logging output template, blob name, and file size limit. (“输出模板”是一个消息模板,除了通过 ILogger 方法调用提供的内容之外,还可将其应用于所有日志。 )(Output template is a message template that's applied to all logs in addition to what's provided with an ILogger method call.)

在部署应用服务应用时,应用程序将采用 Azure 门户中“应用服务”页面下的应用服务日志部分的设置 。When you deploy to an App Service app, the application honors the settings in the App Service logs section of the App Service page of the Azure portal. 更新以下设置后,更改立即生效,无需重启或重新部署应用。When the following settings are updated, the changes take effect immediately without requiring a restart or redeployment of the app.

  • 应用程序日志记录(Filesystem)Application Logging (Filesystem)
  • 应用程序日志记录(Blob)Application Logging (Blob)

日志文件的默认位置是 D:\home\LogFiles\Application 文件夹,默认文件名为 diagnostics-yyyymmdd.txt 。The default location for log files is in the D:\home\LogFiles\Application folder, and the default file name is diagnostics-yyyymmdd.txt. 默认文件大小上限为 10 MB,默认最大保留文件数为 2。The default file size limit is 10 MB, and the default maximum number of files retained is 2. 默认 blob 名为 {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt 。The default blob name is {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

该提供程序仅当项目在 Azure 环境中运行时有效。The provider only works when the project runs in the Azure environment. 项目在本地运行时,该提供程序无效 — 它不会写入本地文件或 blob 的本地开发存储。It has no effect when the project is run locally—it doesn't write to local files or local development storage for blobs.

Azure 日志流式处理Azure log streaming

通过 Azure 日志流式处理,可从以下位置实时查看日志活动:Azure log streaming lets you view log activity in real time from:

  • 应用服务器The app server
  • Web 服务器The web server
  • 请求跟踪失败Failed request tracing

要配置 Azure 日志流式处理,请执行以下操作:To configure Azure log streaming:

  • 从应用的门户页导航到“应用服务日志”页 。Navigate to the App Service logs page from your app's portal page.
  • 将“应用程序日志记录(Filesystem)”设置为“开” 。Set Application Logging (Filesystem) to On.
  • 选择日志级别 。Choose the log Level. 此设置仅适用于 Azure 日志流,不适用于应用中的其他日志记录提供程序。This setting only applies to Azure log streaming, not other logging providers in the app.

导航到“日志流”页面来查看应用消息 。Navigate to the Log Stream page to view app messages. 它们由应用通过 ILogger 接口记录。They're logged by the app through the ILogger interface.

Azure Application Insights 跟踪日志记录Azure Application Insights trace logging

Microsoft.Extensions.Logging.ApplicationInsights 提供程序包将日志写入 Azure Application Insights。The Microsoft.Extensions.Logging.ApplicationInsights provider package writes logs to Azure Application Insights. Application Insights 是一项服务,可监视 Web 应用并提供用于查询和分析遥测数据的工具。Application Insights is a service that monitors a web app and provides tools for querying and analyzing the telemetry data. 如果使用此提供程序,则可以使用 Application Insights 工具来查询和分析日志。If you use this provider, you can query and analyze your logs by using the Application Insights tools.

日志记录提供程序作为 Microsoft.ApplicationInsights.AspNetCore(这是提供 ASP.NET Core 的所有可用遥测的包)的依赖项包括在内。The logging provider is included as a dependency of Microsoft.ApplicationInsights.AspNetCore, which is the package that provides all available telemetry for ASP.NET Core. 如果使用此包,则无需安装提供程序包。If you use this package, you don't have to install the provider package.

请勿使用用于 ASP.NET 4.x 的 Microsoft.ApplicationInsights.Web 包—。Don't use the Microsoft.ApplicationInsights.Web package—that's for ASP.NET 4.x.

有关更多信息,请参见以下资源:For more information, see the following resources:

第三方日志记录提供程序Third-party logging providers

适用于 ASP.NET Core 的第三方日志记录框架:Third-party logging frameworks that work with ASP.NET Core:

某些第三方框架可以执行语义日志记录(又称结构化日志记录)Some third-party frameworks can perform semantic logging, also known as structured logging.

使用第三方框架类似于使用以下内置提供程序之一:Using a third-party framework is similar to using one of the built-in providers:

  1. 将 NuGet 包添加到你的项目。Add a NuGet package to your project.
  2. 调用日志记录框架提供的 ILoggerFactory 扩展方法。Call an ILoggerFactory extension method provided by the logging framework.

有关详细信息,请参阅各提供程序的相关文档。For more information, see each provider's documentation. Microsoft 不支持第三方日志记录提供程序。Third-party logging providers aren't supported by Microsoft.

其他资源Additional resources