ASP.NET Core 中的記錄Logging in ASP.NET Core

作者:Steve SmithTom DykstraBy Steve Smith and Tom Dykstra

ASP.NET Core 支援記錄 API,此 API 能與各種內建和第三方記錄提供者搭配使用。ASP.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) =>
        {
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
        })
        .UseStartup<Startup>()
        .Build();

    webHost.Run();
}

預設專案範本會呼叫 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();
        });

若要使用提供者,請安裝其 NuGet 套件,並在 ILoggerFactory 的執行個體上呼叫該提供者的擴充方法:To use a provider, install its NuGet package and call the provider's extension method on an instance of ILoggerFactory:

public void Configure(IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory
        .AddConsole()
        .AddDebug();

ASP.NET Core 相依性插入 (DI) 提供 ILoggerFactory 執行個體。ASP.NET Core dependency injection (DI) provides the ILoggerFactory instance. AddConsoleAddDebug 擴充方法定義於 Microsoft.Extensions.Logging.ConsoleMicrosoft.Extensions.Logging.Debug 套件中。The AddConsole and AddDebug extension methods are defined in the Microsoft.Extensions.Logging.Console and Microsoft.Extensions.Logging.Debug packages. 每個擴充方法會呼叫 ILoggerFactory.AddProvider 方法,並傳入提供者的執行個體。Each extension method calls the ILoggerFactory.AddProvider method, passing in an instance of the provider.

注意

範例應用程式會在 Startup.Configure 方法中新增記錄提供者。The sample app adds logging providers in the Startup.Configure method. 若要從先前執行的程式碼取得記錄輸出,請在 Startup 類別建構函式中新增記錄提供者。To obtain log output from code that executes earlier, add logging providers in the Startup class constructor.

在此文章中深入了解內建記錄提供者第三方記錄提供者Learn more about built-in logging providers and third-party logging providers later in the article.

建立記錄Create logs

從 DI 取得 ILogger<TCategoryName> 物件。Get an ILogger<TCategoryName> object from DI.

下列控制器範例會建立 InformationWarning 記錄。The following controller example creates Information and Warning logs. 「類別」 是 TodoApiSample.Controllers.TodoController (範例應用程式中 TodoController 的完整類別名稱):The category is TodoApiSample.Controllers.TodoController (the fully qualified class name of TodoController in the sample app):

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

    public TodoController(ITodoRepository todoRepository,
        ILogger<TodoController> logger)
    {
        _todoRepository = todoRepository;
        _logger = logger;
    }
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);
}

下鎳 Razor Pages 範例會建立記錄,其中「層級」lInformation 且「類別」 為 TodoApiSample.Pages.AboutModelThe following Razor Pages example creates logs with Information as the level and TodoApiSample.Pages.AboutModel as the category:

public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
public void OnGet()
{
    Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
    _logger.LogInformation("Message displayed: {Message}", Message);
}
public class TodoController : Controller
{
    private readonly ITodoRepository _todoRepository;
    private readonly ILogger _logger;

    public TodoController(ITodoRepository todoRepository,
        ILogger<TodoController> logger)
    {
        _todoRepository = todoRepository;
        _logger = logger;
    }
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);
}

前述範例會建立記錄,其中「層級」 為 InformationWarning 且「類別」 為 TodoController類別。The preceding example creates logs with Information and Warning as the level and TodoController class as the category.

記錄「層級」 指出已記錄事件的嚴重性。The Log level indicates the severity of the logged event. 記錄「類別」 是與每個記錄關聯的字串。The log category is a string that is associated with each log. ILogger<T> 執行個體會建立使用類型 T 做為類別之完整名稱的記錄。The ILogger<T> instance creates logs that have the fully qualified name of type T as the category. 此文章稍後將詳細說明層級類別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();
    }
}

在程式中建立記錄Create logs in Program

若要在 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();
        });

無非同步記錄器方法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.

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 Vault的加密使用者存放區。An 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. 在範例中,System 與d Microsoft 類別會在 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.

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

LogLevel 索引鍵代表記錄名稱。LogLevel keys represent log names. Default 索引鍵會套用到未明確列出的記錄。The Default key applies to logs not explicitly listed. 此值代表套用到指定記錄的記錄層級The value represents the log level applied to the given log.

如需有關如何實作設定提供者的詳細資訊,請參閱 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.Controllers.TodoController" 為開頭。The logs that are created by the ILogger calls shown in the preceding section begin with "TodoApi.Controllers.TodoController". 開頭為 "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;
    }
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");
    }
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);
}
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);
}

在上述程式碼中,第一個參數是記錄事件識別碼In the preceding code, the first parameter 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 article.

在方法名稱中包含層級的記錄方法 (例如 LogInformationLogWarning) 是 ILogger 的擴充方法Log methods that include the level in the method name (for example, LogInformation and LogWarning) are extension methods for ILogger. 這些方法會呼叫接受 Log 參數的 LogLevelThese 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:

  • 在生產環境中,透過 Information 層級將 Trace 傳送到大量資料存放區。In production, send Trace through Information level to a volume data store. 透過 CriticalWarning 傳送到值資料存放區。Send Warning through Critical to a value data store.
  • 在開發期間,透過 CriticalWarning 傳送到主控台,並在進行疑難排解時透過 Information 新增 TraceDuring development, send Warning through Critical to the console, and add Trace through Information 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

記錄事件識別碼Log event 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;
}
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;
}

事件識別碼會將一組事件關聯。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.

記錄提供者可能將事件識別碼存放到識別碼欄位、記錄訊息中或完全不存放。The logging provider may store the event ID in an ID field, in the logging message, or not at all. 偵錯提供者不會顯示事件識別碼。The Debug provider doesn't show event IDs. 主控台提供者會在類別後面以括弧顯示事件識別碼: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);
}
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);
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.

TodoApi.Controllers.TodoController:Warning: GetById(036dd898-fb01-47e8-9a65-f92eb73cf924) NOT FOUND

System.Exception: Item not found exception.
 at TodoApi.Controllers.TodoController.GetById(String id) in C:\logging\sample\src\TodoApi\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 以設定主控台與偵錯提供者的記錄。The project template code calls CreateDefaultBuilder to set up logging for the Console and Debug providers. CreateDefaultBuilder 方法也會使用如下所示的程式碼,將記錄設定為尋找 Logging 區段中的組態:The CreateDefaultBuilder method also sets up logging to look for configuration in a Logging section, using code like the following:

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) =>
        {
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
        })
        .UseStartup<Startup>()
        .Build();

    webHost.Run();
}

組態資料會依提供者和類別指定最低記錄層級,如下列範例所示: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 會建立六個篩選規則:一個適用於偵錯提供者、四個適用於主控台提供者,一個適用於所有提供者。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.

numberNumber 提供者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 系統System 偵錯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;
        });
    });

某些記錄提供者可讓您指定何時應該將記錄寫入儲存媒體,何時應該根據記錄層級和類別加以略過。Some logging providers let you specify when logs should be written to a storage medium or ignored based on log level and category.

AddConsoleAddDebug 擴充方法提供多載,可接受篩選條件。The AddConsole and AddDebug extension methods provide overloads that accept filtering criteria. 下列範例程式碼會使主控台提供者略過 Warning 層級以下的記錄,而偵錯提供者則會略過架構所建立的記錄。The following sample code causes the console provider to ignore logs below Warning level, while the Debug provider ignores logs that the framework creates.

public void Configure(IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory
        .AddConsole(LogLevel.Warning)
        .AddDebug((category, logLevel) => (category.Contains("TodoApi") && logLevel >= LogLevel.Trace));

AddEventLog 方法具有接受 EventLogSettings 執行個體的多載,其 Filter 屬性中可能包含篩選函式。The AddEventLog method has an overload that takes an EventLogSettings instance, which may contain a filtering function in its Filter property. TraceSource 提供者未提供上述任何多載,因為其記錄層級和其他參數會根據其所使用的 SourceSwitchTraceListenerThe TraceSource provider doesn't provide any of those overloads, since its logging level and other parameters are based on the SourceSwitch and TraceListener it uses.

若要為已向 ILoggerFactory 執行個體註冊的所有提供者設定篩選規則,請使用 WithFilter 擴充方法。To set filtering rules for all providers that are registered with an ILoggerFactory instance, use the WithFilter extension method. 下列範例會將架構記錄 (開頭為 "Microsoft" 或 "System" 的類別) 限制為警告,同時在偵錯層級記錄由應用程式程式碼所建立的記錄。The example below limits framework logs (category begins with "Microsoft" or "System") to warnings while logging at debug level for logs created by application code.

public void Configure(IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory
        .WithFilter(new FilterLoggerSettings
        {
            { "Microsoft", LogLevel.Warning },
            { "System", LogLevel.Warning },
            { "ToDoApi", LogLevel.Debug }
        })
        .AddConsole()
        .AddDebug();

若要防止寫入任何記錄,請指定 LogLevel.None 做為最低記錄層級。To prevent any logs from being written, 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).

WithFilter 擴充方法是由 Microsoft.Extensions.Logging.Filter NuGet 套件提供。The WithFilter extension method is provided by the Microsoft.Extensions.Logging.Filter NuGet package. 此方法會傳回新的 ILoggerFactory 執行個體,這會篩選傳遞至用它來註冊之所有記錄器提供者的記錄訊息。The method returns a new ILoggerFactory instance that will filter the log messages passed to all logger providers registered with it. 它不會影響任何其他 ILoggerFactory 執行個體,包括原始 ILoggerFactory 執行個體。It doesn't affect any other ILoggerFactory instances, including the original ILoggerFactory instance.

系統類別與層級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. HTTPS 憑證資訊。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. 例如,在處理邀交易時建立的每個記錄都可以包括該交易識別碼。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.csProgram.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.

Program.csProgram.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.

Startup.csStartup.cs:

public void Configure(IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory
        .AddConsole(includeScopes: true)
        .AddDebug();

每個記錄訊息包含範圍資訊:Each log message includes the scoped information:

info: TodoApi.Controllers.TodoController[1002]
      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApi.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
      Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApi.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:

如需關於 stdout 記錄的資訊,請參閱針對 IIS 上的 ASP.NET Core 進行疑難排解針對 Azure App Service 上的 ASP.NET Core 進行疑難排解For information about stdout logging, see 針對 IIS 上的 ASP.NET Core 進行疑難排解 and 針對 Azure App Service 上的 ASP.NET Core 進行疑難排解.

Console 提供者Console provider

Microsoft.Extensions.Logging.Console 提供者套件會將記錄輸出傳送至主控台。The Microsoft.Extensions.Logging.Console provider package sends log output to the console.

logging.AddConsole();
loggerFactory.AddConsole();

AddConsole 多載可讓您傳入最低記錄層級、篩選函式,以及指出是否支援範圍的布林值。AddConsole overloads let you pass in a minimum log level, a filter function, and a boolean that indicates whether scopes are supported. 另一個選項是傳入可指定範圍支援和記錄層級的 IConfiguration 物件。Another option is to pass in an IConfiguration object, which can specify scopes support and logging levels.

主控台提供者對效能有重大影響,因此通常不適合在生產環境中使用。The console provider has a significant impact on performance and is generally not appropriate for use in production.

當您在 Visual Studio 中建立新的專案時,AddConsole 方法看起來像這樣:When you create a new project in Visual Studio, the AddConsole method looks like this:

loggerFactory.AddConsole(Configuration.GetSection("Logging"));

此程式碼會參考 appSettings.json 檔案的 Logging 區段:This code refers to the Logging section of the appSettings.json file:

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

上述設定會將架構記錄限制為警告,同時讓應用程式在偵錯層級記錄,如記錄篩選一節中所述。The settings shown limit framework logs to warnings while allowing the app to log at debug level, as explained in the Log filtering section. 如需詳細資訊,請參閱組態For more information, see Configuration.

若要查看主控台記錄輸出,請在專案資料夾中開啟命令提示字元,然後執行下列命令:To see console logging output, open a command prompt in the project folder and run the following command:

dotnet run

Debug 提供者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/messageOn Linux, this provider writes logs to /var/log/message.

logging.AddDebug();
loggerFactory.AddDebug();

AddDebug 多載可讓您傳入最低記錄層級或篩選函式。AddDebug overloads let you pass in a minimum log level or a filter function.

EventSource 提供者EventSource provider

針對以 ASP.NET Core 1.1.0 或更新版本為目標的應用程式,Microsoft.Extensions.Logging.EventSource 提供者套件可以實作事件追蹤。For apps that target ASP.NET Core 1.1.0 or later, the Microsoft.Extensions.Logging.EventSource provider package can implement event tracing. 在 Windows 上,它會使用 ETWOn Windows, it uses ETW. 提供者可以跨平台,但目前沒有適用於 Linux 或 macOS 的事件收集和顯示工具。The provider is cross-platform, but there are no event collection and display tools yet for Linux or macOS.

logging.AddEventSourceLogger();
loggerFactory.AddEventSourceLogger();

收集及檢視記錄的一個好方法是使用 PerfView 公用程式A good way to collect and view logs is to use the PerfView utility. 此外還有一些其他工具可檢視 ETW 記錄,但 PerfView 提供處理 ASP.NET 所發出之 ETW 事件的最佳體驗。There are other tools for viewing ETW logs, but PerfView provides the best experience for working with the ETW events emitted by ASP.NET.

若要設定 PerfView 以收集此提供者所記錄的事件,請將字串 *Microsoft-Extensions-Logging 新增至 [其他提供者] 清單To 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();
loggerFactory.AddEventLog();

AddEventLog 多載可讓您傳入 EventLogSettings 或最低記錄層級。AddEventLog overloads let you pass in EventLogSettings or a minimum log level.

TraceSource 提供者TraceSource provider

Microsoft.Extensions.Logging.TraceSource 提供者套件使用 TraceSource 程式庫與提供者。The Microsoft.Extensions.Logging.TraceSource provider package uses the TraceSource libraries and providers.

logging.AddTraceSource(sourceSwitchName);
loggerFactory.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.

下列範例會設定 TraceSource 提供者,將 Warning 和更高層級訊息記錄至主控台視窗。The following example configures a TraceSource provider that logs Warning and higher messages to the console window.

public void Configure(IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory
        .AddDebug();

    // add Trace Source logging
    var testSwitch = new SourceSwitch("sourceSwitch", "Logging Sample");
    testSwitch.Level = SourceLevels.Warning;
    loggerFactory.AddTraceSource(testSwitch,
        new TextWriterTraceListener(writer: Console.Out));

Azure App Service 提供者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. 提供者套件適用於以 .NET Core 1.1 或更新版本為目標的應用程式。The provider package is available for apps targeting .NET Core 1.1 or later.

若以 .NET Core 為目標,請注意下列幾點:If targeting .NET Core, note the following points:

若以 .NET Framework 為目標,或是參考 Microsoft.AspNetCore.App 中繼套件,請將提供者套件新增至專案。If targeting .NET Framework or referencing the Microsoft.AspNetCore.App metapackage, add the provider package to the project. 叫用 AddAzureWebAppDiagnosticsInvoke AddAzureWebAppDiagnostics:

logging.AddAzureWebAppDiagnostics();
loggerFactory.AddAzureWebAppDiagnostics();

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.)

如果要進行提供者設定,請使用 AzureFileLoggerOptionsAzureBlobLoggerOptions,如以下範例中所示:To configure provider settings, use AzureFileLoggerOptions and AzureBlobLoggerOptions, as shown in the following example:

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

當您部署到 App Service 應用程式時,應用程式會遵循 Azure 入口網站 [App Service] 頁面中 App Service 記錄區段的設定。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.

  • 應用程式記錄 (檔案系統)Application Logging (Filesystem)
  • 應用程式記錄 (Blob)Application Logging (Blob)

記錄檔的預設位置為 D:\home\LogFiles\Application 資料夾,而預設檔案名稱為 diagnostics-yyyymmdd.txtThe 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.txtThe 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
  • 網頁伺服器The web server
  • 失敗的要求追蹤Failed request tracing

若要設定 Azure 記錄資料流:To configure Azure log streaming:

  • 從您應用程式的入口網站頁面瀏覽到 [App Service 記錄] 。Navigate to the App Service logs page from your app's portal page.
  • 將 [應用程式記錄 (檔案系統)] 設定為 [開啟] 。Set Application Logging (Filesystem) to On.
  • 選擇記錄 [層級] 。Choose the log Level.

瀏覽到 [記錄資料流] 頁面以檢視應用程式訊息。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.

不要使用 Microsoft.ApplicationInsights.Web (英文) 套件—該套件適用於 ASP.NET 4.x。Don't use the Microsoft.ApplicationInsights.Web package—that's for ASP.NET 4.x.

如需詳細資訊,請參閱下列資源:For more information, see the following resources:

注意

自 5/1/2019 起,標題為適用於 ASP.NET Core 的 Application Insights 的文章已過時,因此教學課程步驟已不適用。As of 5/1/2019, the article titled Application Insights for ASP.NET Core is out of date, and the tutorial steps don't work. 請改為參閱適用於 ASP.NET Core 應用程式的 Application InsightsRefer to Application Insights for ASP.NET Core applications instead. 我們已知道此問題且正致力於更正它。We are aware of the issue and are working to correct it.

協力廠商記錄提供者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. 呼叫 ILoggerFactoryCall an ILoggerFactory.

如需詳細資訊,請參閱每個提供者的文件。For more information, see each provider's documentation. Microsoft 不支援第三方記錄提供者。Third-party logging providers aren't supported by Microsoft.

其他資源Additional resources