.NET Core 和 ASP.NET Core 中的記錄 (機器翻譯)

作者:Kirk LarkinJuergen GutschRick Anderson

本文說明 .NET 中的記錄,因為它適用於 ASP.NET Core 應用程式。 如需在 .NET 中記錄的詳細資訊,請參閱在 .NET 中記錄。 如需有關在 Blazor 應用程式中記錄的詳細資訊,請參閱 ASP.NET Core Blazor 記錄

記錄提供者

記錄提供者會儲存記錄,但顯示記錄的 Console 提供者則除外。 例如,Azure Application Insights 提供者會將記錄儲存在 Azure Application Insights 中。 您可以啟用多個提供者。

預設 ASP.NET Core Web 應用程式範本會呼叫 WebApplication.CreateBuilder,這會新增下列記錄提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

上述程式碼會顯示使用 ASP.NET Core Web 應用程式範本建立的 Program.cs 檔案。 接下來的數個區段會根據 ASP.NET Core Web 應用程式範本提供範例。

下列程式碼會覆寫 WebApplication.CreateBuilder 所新增的記錄提供者預設集:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

或者,上述記錄程式碼可以撰寫如下:

var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
    logging.ClearProviders();
    logging.AddConsole();
});

如需其他提供者,請參閱:

建立記錄

若要建立記錄,請使用ILogger<TCategoryName>相依性插入 (DI) 的物件。

下列範例將:

  • 建立記錄器 (ILogger<AboutModel>),這個記錄器會使用類型 AboutModel 完整名稱的記錄類別。 記錄「類別」是與每個記錄關聯的字串。
  • 呼叫 LogInformation 以在 Information 層級記錄。 記錄「層級」 指出已記錄事件的嚴重性。
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

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

    public void OnGet()
    {
        _logger.LogInformation("About page visited at {DT}", 
            DateTime.UtcNow.ToLongTimeString());
    }
}

此文件稍後將詳細說明層級類別

如需 Blazor 的相關資訊,請參閱ASP.NET CoreBlazor 記錄

設定記錄

記錄組態通常是由 appsettings.{ENVIRONMENT}.json 檔案的 Logging 區段所提供,其中 {ENVIRONMENT} 預留位置是環境。 下列 appsettings.Development.json 檔案是由 ASP.NET Core Web 應用程式範本所產生:

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

在上述 JSON 中:

  • 指定 "Default""Microsoft.AspNetCore" 類別。
  • "Microsoft.AspNetCore" 類別會套用至開頭為 "Microsoft.AspNetCore" 的所有類別。 例如,此設定適用於 "Microsoft.AspNetCore.Routing.EndpointMiddleware" 類別。
  • 記錄層級 Warning 和更高層級的 "Microsoft.AspNetCore" 類別記錄。
  • 未指定特定的記錄提供者,因此 LogLevel 適用於 Windows EventLog 以外的所有已啟用記錄提供者。

Logging 屬性可以有 LogLevel 與記錄提供者屬性。 LogLevel 會指定要針對所選類別記錄的最小層級。 在上述 JSON 中,會指定 InformationWarning 記錄層級。 LogLevel 表示記錄的嚴重性,範圍從 0 到 6:

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

指定 LogLevel 時,會針對指定層級和更高層級的訊息啟用記錄。 在上述 JSON 中,Default 類別會記錄為 Information 和更新版本。 例如,會記錄 InformationWarningErrorCritical 訊息。 如果未指定 LogLevel,則記錄預設為 Information 層級。 如需詳細資訊,請參閱記錄層級

提供者屬性可以指定 LogLevel 屬性。 LogLevel 在提供者下,會指定要針對該提供者記錄的層級,並覆寫非提供者記錄設定。 請考量下列 appsettings.json 檔案:

{
  "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.{PROVIDER NAME}.LogLevel 中的設定會覆寫 Logging.LogLevel 中的設定,其中 {PROVIDER NAME} 預留位置是提供者名稱。 在上述 JSON 中,Debug 提供者的預設記錄層級會設定為 Information

Logging:Debug:LogLevel:Default:Information

上述設定會指定每個 Logging:Debug: 類別的 Information 記錄層級,但 Microsoft.Hosting 除外。 列出特定類別時,特定類別會覆寫預設類別。 在上述 JSON 中,Logging:Debug:LogLevel 類別 "Microsoft.Hosting""Default" 會覆寫 Logging:LogLevel 中的設定。

您可以針對下列任一項目指定最小記錄層級:

  • 特定提供者:例如 Logging:EventSource:LogLevel:Default:Information
  • 特定類別:例如 Logging:LogLevel:Microsoft:Warning
  • 所有提供者和所有類別:Logging:LogLevel:Default:Warning

低於最低層級的任何記錄都不是

  • 傳遞至提供者。
  • 已記錄或顯示。

若要隱藏所有記錄,請指定 LogLevel.NoneLogLevel.None 的值為 6,其高於 LogLevel.Critical (5)。

若提供者支援記錄範圍IncludeScopes 會指出是否已啟用記錄範圍。 如需詳細資訊,請參閱記錄範圍

下列 appsettings.json 檔案包含預設啟用的所有提供者:

{
  "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"
      }
    }
  }
}

在上述範例中:

  • 類別和層級不是建議的值。 此範例會提供以顯示所有預設提供者。
  • Logging.{PROVIDER NAME}.LogLevel 中的設定會覆寫 Logging.LogLevel 中的設定,其中 {PROVIDER NAME} 預留位置是提供者名稱。 例如,Debug.LogLevel.Default 中的層級會覆寫 LogLevel.Default 中的層級。
  • 會使用每個預設提供者「別名」。 每個提供者都會定義「別名」,可在設定中用來取代完整類型名稱。 內建提供者別名如下:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

登入 Program.cs

下列範例會呼叫 Program.cs 中的 Builder.WebApplication.Logger,並記錄參考訊息:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();

下列範例會在 Program.cs 中呼叫 AddConsole 並記錄 /Test 端點:

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

下列範例會在 Program.cs 中呼叫 AddSimpleConsole、停用色彩輸出,並記錄 /Test 端點:

using Microsoft.Extensions.Logging.Console;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

依命令列、環境變數和其他組態設定記錄層級

記錄層級可由任何設定提供者進行設定。

: 分隔符號不適用於所有平台上的環境變數階層式機碼。 __,雙底線,為:

  • 所有平台都支援。 例如,Bash 不支援 : 分隔符號,但支援 __
  • 自動由 : 取代

下列 命令:

  • 將環境索引鍵 Logging:LogLevel:Microsoft 設定為 Windows 上的 Information 值。
  • 使用搭配 ASP.NET Core Web 應用程式範本建立的應用程式時,請測試設定。 在使用 set 之後,必須在專案目錄中執行 dotnet run 命令。
set Logging__LogLevel__Microsoft=Information
dotnet run

上述環境設定:

  • 只會在從其所設定命令視窗啟動的程序中進行設定。
  • 不會由使用 Visual Studio 啟動的瀏覽器讀取。

下列 setx 命令也會設定 Windows 上的環境索引鍵和值。 不同於 setsetx 設定會予以保存。 /M 參數會在系統內容中設定變數。 如果未使用 /M,則會設定使用者環境變數。

setx Logging__LogLevel__Microsoft Information /M

請考量下列 appsettings.json 檔案:

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace"
    }
  }
}

下列命令會在環境中設定上述組態:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

注意

在 macOS 和 Linux 中使用包含 . (句號) 的名稱來設定環境變數時,請考慮 Stack Exchange 上關於 "Exporting a variable with a dot (.) in it" (匯出具有點 (.) 的變數) 的問題,以及其對應的公認答案 (英文)。

Azure App Service 上,選取 [設定] > [組態] 頁面上的 [新增應用程式設定]。 Azure App Service 應用程式設定為:

  • 在待用及透過加密通道傳輸時加密。
  • 公開為環境變數。

如需詳細資訊,請參閱 Azure Apps:使用 Azure 入口網站 覆寫應用程式設定。

如需使用環境變數設定 ASP.NET Core 組態值的詳細資訊,請參閱環境變數。 如需使用其他組態來源 (包括命令列、Azure Key Vault、Azure 應用程式組態、其他檔案格式等等) 的相關資訊,請參閱 ASP.NET Core 的設定

如何套用篩選規則

建立 ILogger<TCategoryName> 物件時,ILoggerFactory 物件會針對每個提供者選取一個規則來套用到該記錄器。 由 ILogger 執行個體寫入的所有訊息都會根據選取的規則進行篩選。 系統會從可用的規則中,選取對每個提供者和類別配對最明確的規則。

當建立指定類別的 ILogger 時,系統會針對每個提供者使用下列演算法:

  • 選取所有符合提供者或其別名的規則。 如果找不到符合的項目,請選取所有規則搭配空白提供者。
  • 從上一個步驟的結果中,選取具有最長相符類別前置字元的規則。 如果找不到符合的項目,請選取未指定類別的所有規則。
  • 如果選取多個規則,請使用最後一個。
  • 如果未選取任何規則,請使用 MinimumLevel

記錄 dotnet run 和 Visual Studio 的輸出

使用預設記錄提供者建立的記錄會顯示:

  • 在 Visual Studio 中
    • 在 [偵錯輸出] 視窗中 (偵錯時)。
    • 在 [ASP.NET Core Web 伺服器] 視窗中。
  • 在主控台視窗中 (使用 dotnet run 執行應用程式時)。

開頭為 "Microsoft" 類別的記錄則是來自 ASP.NET Core 架構程式碼。 ASP.NET Core 與應用程式程式碼會使用相同的記錄 API 與提供者。

記錄類別

建立 ILogger 物件時,會指定「類別」。 該類別會包含在每個由該 ILogger 執行個體所產生的記錄訊息中。 類別字串是任意的,但慣例是使用完整類別名稱。 例如,在控制器中,名稱可能是 "TodoApi.Controllers.TodoController"。 ASP.NET Core Web 應用程式會使用 ILogger<T> 來自動取得 ILogger 執行個體,該執行個體會使用 T 的完整類型名稱來做為類別:

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.CreateLogger階層式名稱:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

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

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

在多個方法中使用時,以固定名稱呼叫 CreateLogger 可能會很有用,因此可依類別來組織事件。

ILogger<T> 相當於使用 T的完整類型名稱來呼叫 CreateLogger

記錄等級

下表列出 LogLevel 值、便利的 Log{LogLevel} 擴充方法和建議的使用方式:

LogLevel 方法 描述
Trace 0 LogTrace 包含最詳細的訊息。 這些訊息可能包含敏感性應用程式資料。 這些訊息預設會停用,且應在生產環境中啟用。
Debug 1 LogDebug 用於偵錯和開發。 由於大量,因此在生產環境中請謹慎使用。
Information 2 LogInformation 追蹤一般應用程式流程。 可能具有長期值。
Warning 3 LogWarning 針對異常或意外事件。 通常包含不會導致應用程式失敗的錯誤或狀況。
Error 4 LogError 發生無法處理的錯誤和例外狀況。 這些訊息指出目前作業或要求中發生失敗,而不是整個應用程式的失敗。
Critical 5 LogCritical 發生需要立即注意的失敗。 範例:資料遺失情況、磁碟空間不足。
None 6 指定記錄類別不應寫入訊息。

在上表中,會從最低到最高嚴重性列出 LogLevel

Log 方法的第一個參數 (LogLevel) 表示記錄的嚴重性。 大部分開發人員會呼叫 Log{LOG LEVEL} 擴充方法 (其中 {LOG LEVEL} 預留位置是記錄層級),而不是呼叫 Log(LogLevel, ...)。 例如,下列兩個記錄呼叫在功能上相等,並產生相同的記錄:

[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 為事件識別碼。 MyLogEvents 是範例應用程式的一部分,且會顯示在記錄事件識別碼區段中。

MyDisplayRouteInfo 和 ToCtxString 是由 Rick.Docs.Samples.RouteInfo NuGet 套件提供。 方法會顯示 ControllerRazor Page 路由資訊。

下列程式碼會建立 InformationWarning 記錄:

[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{LOG LEVEL} 參數 (MyLogEvents.GetItem) 是記錄事件識別碼。 第二個參數是訊息範本,其中的預留位置會置入其餘方法參數所提供的引數值。 此文件稍後的訊息範本小節將詳細說明方法參數。

呼叫適當的 Log{LOG LEVEL} 方法來控制要寫入至特定儲存媒體的記錄輸出量。 例如:

  • 生產環境:
    • TraceDebugInformation 層級的記錄會產生大量的詳細記錄訊息。 若要控制成本,且不超過資料儲存體限制,請將 TraceDebugInformation 層級訊息記錄為大量、低成本的資料存放區。 請考慮將 TraceDebugInformation 限制為特定類別。
    • 透過 Critical 層級的 Warning 記錄應該會產生一些記錄訊息。
      • 成本和儲存體限制通常無所謂。
      • 記錄數少可讓資料存放區選擇更具彈性。
  • 開發中:
    • 設定為 Warning
    • 進行疑難排解時,新增 TraceDebugInformation 訊息。 若要限制輸出,請僅針對調查中的類別設定 TraceDebugInformation

ASP.NET Core 會寫入架構事件的記錄。 例如,請考慮下列項目的記錄輸出:

  • 使用 ASP.NET Core 範本建立的 Razor Pages 應用程式。
  • 記錄設定為 Logging:Console:LogLevel:Microsoft:Information
  • 瀏覽至 Privacy 頁面:
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:Information

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

記錄事件識別碼

每個記錄都可以指定「事件識別碼」。 範例應用程式會使用 MyLogEvents 類別來定義事件識別碼:

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

事件識別碼會將一組事件關聯。 例如,與在頁面上顯示項目清單相關的所有記錄可能都是 1001。

記錄提供者可能將事件識別碼存放到識別碼欄位、記錄訊息中或完全不存放。 偵錯提供者不會顯示事件識別碼。 主控台提供者會在類別後面以括弧顯示事件識別碼:

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

有些記錄提供者會將事件識別碼儲存在欄位中,以允許篩選識別碼。

記錄訊息範本

每個記錄 API 都會使用訊息範本。 訊息範本可以包含有關提供哪個引數的預留位置。 使用名稱而非數字做為預留位置。

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

參數的順序 (而不是其預留位置名稱) 會決定哪些參數可用來在記錄訊息中提供預留位置值。 在下列程式碼中,參數名稱在訊息範本的預留位置中未依順序出現:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {Pears}, {Bananas}, {Apples}", apples, pears, bananas);

不過,參數會依序指派給預留位置:applespearsbananas。 記錄訊息會反映「參數的順序」

Parameters: 1, 2, 3

此方法可讓記錄提供者實作語意或結構化記錄。 引數本身會被傳遞到記錄系統,而不只是格式化的訊息範本。 這可讓記錄提供者將參數值儲存為欄位。 例如,請考量下列記錄器方法:

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

例如,登入 Azure 資料表儲存體時:

  • 每個 Azure 資料表實體都可以有 IDRequestTime 屬性。
  • 具有屬性的資料表可簡化針對記錄資料的查詢。 例如,查詢可以尋找特定 RequestTime 範圍內的所有記錄,而不必剖析文字訊息中的時間。

記錄例外狀況

記錄器方法具有多載可接受例外狀況參數:

[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 和 ToCtxString 是由 Rick.Docs.Samples.RouteInfo NuGet 套件提供。 方法會顯示 ControllerRazor Page 路由資訊。

例外狀況記錄是提供者特定的。

預設記錄層級

如果未設定預設記錄層級,則預設記錄層級值為 Information

例如,請考量下列 Web 應用程式:

  • 使用 ASP.NET Web 應用程式範本所建立。
  • appsettings.jsonappsettings.Development.json 已刪除或重新命名。

在上述設定中,瀏覽至隱私權或首頁會產生許多類別名稱中具有 MicrosoftTraceDebugInformation 訊息。

下列程式碼會在設定中未設定預設記錄層級時,設定預設記錄層級:

var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

一般而言,應該在組態而不是程式碼中指定記錄層級。

Filter 函式

針對組態或程式碼未指派規則的所有提供者和類別,會叫用篩選函式:

var builder = WebApplication.CreateBuilder();
builder.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;
    }
});

上述程式碼會在類別包含 ControllerMicrosoft 且記錄層級為 Information 或更高層級時顯示主控台記錄。

一般而言,應該在組態而不是程式碼中指定記錄層級。

ASP.NET Core 和 EF Core 類別

下表包含 ASP.NET Core 和 Entity Framework Core 所使用的一些類別,以及記錄的相關注意事項:

類別 備註
Microsoft.AspNetCore 一般 ASP.NET Core 診斷。
Microsoft.AspNetCore.DataProtection 已考慮、發現及使用哪些金鑰。
Microsoft.AspNetCore.HostFiltering 允許主機。
Microsoft.AspNetCore.Hosting HTTP 要求花了多少時間完成,以及其開始時間。 載入了哪些裝載啟動組件。
Microsoft.AspNetCore.Mvc MVC 和 Razor 診斷。 模型繫結、篩選執行、檢視編譯、動作選取。
Microsoft.AspNetCore.Routing 路由比對資訊。
Microsoft.AspNetCore.Server 連線開始、停止與保持運作回應。 HTTPS 憑證資訊。
Microsoft.AspNetCore.StaticFiles 提供的檔案。
Microsoft.EntityFrameworkCore 一般 Entity Framework Core 診斷。 資料庫活動與設定、變更偵測、移轉。

若要在主控台視窗中檢視更多類別,請將 appsettings.Development.json 設定為下列項目:

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

記錄範圍

「範圍」可用來將邏輯作業組成群組。 此分組功能可用來將相同的資料附加到已建立為集合之一部分的每個記錄。 例如,在處理邀交易時建立的每個記錄都可以包括該交易識別碼。

範圍:

下列提供者支援範圍:

透過將記錄器呼叫封裝在 using 區塊中以使用範圍:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _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);
}

內建記錄提供者

ASP.NET Core 包含下列記錄提供者做為共用架構的一部分:

下列記錄提供者是由 Microsoft 提供,但不是共用架構的一部分。 必須將其安裝做為額外的 NuGet。

ASP.NET Core 不包含記錄提供者,可用來將記錄寫入檔案。 若要從 ASP.NET Core 應用程式將記錄寫入檔案,請考慮使用協力廠商記錄提供者

如需使用 ASP.NET Core 模組進行 stdout 和偵錯記錄的相關資訊,請參閱針對 Azure App Service 上的 ASP.NET Core 進行疑難排解,以及 ASP.NET Core Module (ANCM) for IIS

主控台

Console 提供者會將輸出記錄到主控台。 如需在開發中檢視 Console 記錄的相關詳細資訊,請參閱記錄 dotnet run 和 Visual Studio 的輸出

偵錯

Debug 提供者會使用 System.Diagnostics.Debug 類別來寫入記錄輸出。 呼叫 System.Diagnostics.Debug.WriteLine 寫入 Debug 提供者。

在 Linux 上,Debug 提供者記錄位置與散發相依,可能是下列其中一項:

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

事件來源

EventSource 提供者會寫入名稱為 Microsoft-Extensions-Logging 的跨平台事件來源。 在 Windows 上,提供者會使用 ETW

dotnet-trace 工具

dotnet-trace 工具是一種跨平台 CLI 全域工具,可收集執行中程序的 .NET Core 追蹤。 此工具會使用 LoggingEventSource 收集 Microsoft.Extensions.Logging.EventSource 提供者資料。

如需安裝指示,請參閱 dotnet-trace

使用 dotnet-trace 工具從應用程式收集追蹤:

  1. 使用 dotnet run 命令執行應用程式。

  2. 判斷 .NET Core 應用程式的程序識別碼 (PID):

    dotnet-trace ps
    

    尋找與應用程式元件名稱相同程序的 PID。

  3. 執行 dotnet-trace 命令。

    一般命令語法:

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

    使用 PowerShell 命令殼層時,以單引號括住 --providers 值 ('):

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

    在非 Windows 平台上,新增 -f speedscope 選項,將輸出追蹤檔案的格式變更為 speedscope

    下表會定義關鍵字:

    關鍵字 描述
    1 記錄有關 LoggingEventSource 的中繼事件。 不會記錄來自 ILogger 的事件。
    2 呼叫 ILogger.Log() 時,開啟 Message。 以程式設計 (而非格式化) 的方式提供資訊。
    4 呼叫 ILogger.Log() 時,開啟 FormatMessage。 提供資訊的格式化字串版本。
    8 呼叫 ILogger.Log() 時,開啟 MessageJson。 提供引數的 JSON 表示法。

    下表列出提供者層級:

    提供者層級 描述
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    類別層級的剖析可以是字串或數字:

    類別具名值 數值
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    提供者層級和類別層級:

    • 是反向順序。
    • 字串常數不完全相同。

    如果未指定 FilterSpecs,則 EventSourceLogger 實作會嘗試將提供者層級轉換成類別層級,並將其套用至所有類別。

    提供者層級 類別層級
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    如果已提供 FilterSpecs,則清單中所包含的任何類別都會使用在該處編碼的類別層級,並會篩選掉所有其他類別。

    下列範例假設:

    • 應用程式正在執行並呼叫 logger.LogDebug("12345")
    • 已透過 set PID=12345 設定程序識別碼 (PID),其中 12345 是實際的 PID。

    請考慮下列命令:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    上述命令會:

    • 擷取偵錯訊息。
    • 不會套用 FilterSpecs
    • 指定層級 5,其可對應類別偵錯。

    請考慮下列命令:

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    上述命令會:

    • 不會擷取偵錯訊息,因為類別層級 5 是 Critical
    • 可提供 FilterSpecs

    下列命令會擷取偵錯訊息,因為類別層級 1 指定 Debug

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    下列命令會擷取偵錯訊息,因為類別指定 Debug

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    {Logger Category}{Category Level}FilterSpecs 代表其他記錄篩選條件。 以 ; 分號字元分隔 FilterSpecs 項目。

    使用 Windows 命令殼層的範例:

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

    上述命令會啟動︰

    • 事件來源記錄器,可針對錯誤 (2) 產生格式化字串 (4)。
    • Informational 記錄層級 (4) 的 Microsoft.AspNetCore.Hosting 記錄。
  4. dotnet-trace按 Enter 鍵或 Ctrl+C 停止工具。

    追蹤會以 trace.nettrace 名稱儲存在執行 dotnet-trace 命令的資料夾中。

  5. 使用 Perfview 開啟追蹤。 開啟 trace.nettrace 檔案並探索追蹤事件。

如果應用程式未使用 WebApplication.CreateBuilder 建置主機,請將事件來源提供者新增至應用程式的記錄設定。

如需詳細資訊,請參閱

Perfview

使用 PerfView 公用程式來收集和檢視記錄。 此外還有一些其他工具可檢視 ETW 記錄,但 PerfView 提供處理 ASP.NET Core 所發出 ETW 事件的最佳體驗。

若要設定 PerfView 以收集此提供者所記錄的事件,請將字串 *Microsoft-Extensions-Logging 新增至 [其他提供者] 清單 請勿遺漏字串開頭的 *

Windows EventLog

EventLog 提供者會將記錄輸出傳送至 Windows 事件記錄檔。 與其他提供者不同,EventLog 提供者不會繼承預設的非提供者設定。 如果未指定 EventLog 記錄設定,則預設為 LogLevel.Warning

若要記錄低於 LogLevel.Warning 的事件,請明確設定記錄層級。 下列範例會將事件記錄檔預設記錄層級設定為 LogLevel.Information

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

AddEventLog 多載可以傳入 EventLogSettings。 如果 null 或未指定,則會使用下列預設設定:

  • LogName:「應用程式」
  • SourceName:「.NET Runtime」
  • MachineName:使用本機電腦名稱。

下列程式碼會將 SourceName".NET Runtime" 的預設值變更為 MyLogs


var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
    eventLogSettings.SourceName = "MyLogs";
});

Azure App Service

Microsoft.Extensions.Logging.AzureAppServices 提供者套件會將記錄寫入至 Azure App Service 應用程式檔案系統中的文字檔,並寫入至 Azure 儲存體帳戶中的 Blob 儲存體

該提供者套件並未包含在共用架構中。 若要使用提供者,請將提供者套件新增至專案。

如果要進行提供者設定,請使用 AzureFileLoggerOptionsAzureBlobLoggerOptions,如以下範例中所示:

using Microsoft.Extensions.Logging.AzureAppServices;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddAzureWebAppDiagnostics();
builder.Services.Configure<AzureFileLoggerOptions>(options =>
{
    options.FileName = "azure-diagnostics-";
    options.FileSizeLimit = 50 * 1024;
    options.RetainedFileCountLimit = 5;
});
builder.Services.Configure<AzureBlobLoggerOptions>(options =>
{
    options.BlobName = "log.txt";
});

當部署到 Azure App Service 時,應用程式會使用 Azure 入口網站 [App Service] 頁面中 App Service 記錄區段的設定。 當下列設定更新時,變更會立即生效,而不需要重新啟動或重新部署應用程式。

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

記錄檔的預設位置位於 D:\\home\\LogFiles\\Application 資料夾中,而預設檔案名稱為 diagnostics-yyyymmdd.txt。 預設檔案大小限制為 10 MB,而預設保留的檔案數目上限為 2。 預設 Blob 名稱為 {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt

此提供者僅記錄專案在 Azure 環境中執行的情況。

Azure 記錄串流

Azure 記錄串流可支援即時檢視來自下列位置的記錄活動:

  • 應用程式伺服器
  • 網頁伺服器
  • 失敗要求的追蹤

若要設定 Azure 記錄資料流:

  • 從應用程式的入口網站頁面瀏覽到 [App Service 記錄]
  • 將 [應用程式記錄 (檔案系統)] 設定為 [開啟]
  • 選擇記錄 [層級]。 此設定僅適用於 Azure 記錄串流。

瀏覽到 [記錄資料流] 頁面以檢視記錄。 記錄的訊息會與 ILogger 介面一起記錄。

Azure Application Insights

Microsoft.Extensions.Logging.ApplicationInsights 提供者封裝會將記錄寫入 Azure Application Insights。 Application Insights 是可監視 Web 應用程式的服務,並提供可用來查詢及分析遙測資料的工具。 如果您使用此提供者,就可以使用 Application Insights 工具來查詢及分析記錄。

記錄提供者會以 Microsoft.ApplicationInsights.AspNetCore 的相依性形式隨附,這是針對 ASP.NET Core 提供所有可用遙測的套件。 如果您使用此套件,就不需安裝提供者套件。

Microsoft.ApplicationInsights.Web 套件適用於 ASP.NET 4.x,而不適用於 ASP.NET Core。

如需詳細資訊,請參閱以下資源:

協力廠商記錄提供者

可搭配 ASP.NET Core 使用的協力廠商記錄架構:

某些協力廠商架構可以執行語意記錄 (也稱為結構化記錄) \(英文\)。

使用協力廠商架構類似於使用內建的提供者之一:

  1. 將 NuGet 套件新增至專案。
  2. 呼叫記錄架構所提供的 ILoggerFactory 擴充方法。

如需詳細資訊,請參閱每個提供者的文件。 Microsoft 不支援第三方記錄提供者。

無非同步記錄器方法

記錄速度應該很快,不值得花費非同步程式碼的效能成本來處理。 若記錄資料存放區很慢,請不要直接寫入其中。 請考慮一開始將記錄寫入到快速的存放區,稍後再將其移到慢速存放區。 例如,當記錄到 SQL Server 時,請勿在 Log 方法中直接執行,因為 Log 方法是同步的。 相反地,以同步方式將記錄訊息新增到記憶體內佇列,並讓背景工作角色提取出佇列的訊息,藉此執行推送資料到 SQL Server 的非同步工作。 如需詳細資訊,請參閱如何針對慢速資料存放區 (dotnet/AspNetCore.Docs #11801) 登入訊息佇列的指引

變更執行中應用程式的記錄層級

記錄 API 不包含應用程式執行時變更記錄層級的案例。 不過,某些組態提供者能夠重新載入組態,這會立即對記錄組態生效。 例如,檔案組態提供者預設會重新載入記錄組態。 如果應用程式執行時在程式碼中變更組態,則應用程式可以呼叫 IConfigurationRoot.Reload 來更新應用程式的記錄組態。

ILogger 和 ILoggerFactory

ILogger<TCategoryName>ILoggerFactory 介面及實作會包含在 .NET Core SDK 中。 其也可以在下列 NuGet 套件中使用:

在程式碼中套用記錄篩選規則

設定記錄篩選規則的慣用方法是使用組態

下列範例說明如何在程式碼中註冊篩選規則:

using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Debug;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter("System", LogLevel.Debug);
builder.Logging.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information);
builder.Logging.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace);

logging.AddFilter("System", LogLevel.Debug) 會指定 System 類別和記錄層級 Debug。 篩選條件會套用至所有提供者,因為未設定特定提供者。

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) 會指定:

  • Debug 記錄提供者。
  • 記錄層級 Information 和更新版本。
  • "Microsoft" 開始的所有類別。

使用 SpanIdTraceIdParentIdBaggageTags 自動記錄範圍。

記錄程式庫會隱含地使用 SpanIdTraceIdParentIdBaggageTags 來建立範圍物件。 此行為是透過 ActivityTrackingOptions 進行設定。

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(options =>
{
    options.IncludeScopes = true;
});

builder.Logging.Configure(options =>
{
    options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                       | ActivityTrackingOptions.TraceId
                                       | ActivityTrackingOptions.ParentId
                                       | ActivityTrackingOptions.Baggage
                                       | ActivityTrackingOptions.Tags;
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

如果已設定 traceparent http 要求標頭,則記錄範圍中的 ParentId 會顯示來自輸入 traceparent 標頭的 W3C parent-id,而記錄範圍中的 SpanId 會顯示下一個輸出步驟/範圍的更新 parent-id。 如需詳細資訊,請參閱變動 traceparent 欄位

建立自訂記錄器

若要建立自訂記錄器,請參閱在 .NET 中實作自訂記錄提供者

其他資源

作者:Kirk LarkinJuergen GutschRick Anderson

本主題描述在 .NET 中記錄,因為其適用於 ASP.NET Core 應用程式。 如需在 .NET 中記錄的詳細資訊,請參閱在 .NET 中記錄。 如需有關在 Blazor 應用程式中記錄的詳細資訊,請參閱 ASP.NET Core Blazor 記錄

檢視或下載範例程式碼 (如何下載)。

記錄提供者

記錄提供者會儲存記錄,但顯示記錄的 Console 提供者則除外。 例如,Azure Application Insights 提供者會將記錄儲存在 Azure Application Insights 中。 您可以啟用多個提供者。

預設 ASP.NET Core Web 應用程式範本:

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 類別。 接下來的幾節會根據使用泛型主機的 ASP.NET Core Web 應用程式範本來提供範例。 本文件稍後將討論非主機主控台應用程式

若要覆寫 Host.CreateDefaultBuilder 所新增的記錄提供者預設集,請呼叫 ClearProviders 並新增必要的記錄提供者。 例如,下列程式碼:

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

如需其他提供者,請參閱:

建立記錄

若要建立記錄,請使用ILogger<TCategoryName>相依性插入 (DI) 的物件。

下列範例將:

  • 建立記錄器 (ILogger<AboutModel>),這個記錄器會使用類型 AboutModel 完整名稱的記錄類別。 記錄「類別」是與每個記錄關聯的字串。
  • 呼叫 LogInformation 以在 Information 層級記錄。 記錄「層級」 指出已記錄事件的嚴重性。
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);
    }
}

此文件稍後將詳細說明層級類別

如需 Blazor 的相關資訊,請參閱ASP.NET CoreBlazor 記錄

在 Main 和 Startup 中建立記錄示範如何在 MainStartup 中建立記錄。

設定記錄

記錄組態通常是由 appsettings.{Environment}.json 檔案的 Logging 區段所提供。 下列 appsettings.Development.json 檔案是由 ASP.NET Core Web 應用程式範本所產生:

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

在上述 JSON 中:

  • 指定 "Default""Microsoft""Microsoft.Hosting.Lifetime" 類別。
  • "Microsoft" 類別會套用至開頭為 "Microsoft" 的所有類別。 例如,此設定適用於 "Microsoft.AspNetCore.Routing.EndpointMiddleware" 類別。
  • 記錄層級 Warning 和更高層級的 "Microsoft" 類別記錄。
  • "Microsoft.Hosting.Lifetime" 類別比 "Microsoft" 類別更具體,因此 "Microsoft.Hosting.Lifetime" 類別會記錄「資訊」記錄層級和更高層級。
  • 未指定特定的記錄提供者,因此 LogLevel 適用於 Windows EventLog 以外的所有已啟用記錄提供者。

Logging 屬性可以有 LogLevel 與記錄提供者屬性。 LogLevel 會指定要針對所選類別記錄的最小層級。 在上述 JSON 中,會指定 InformationWarning 記錄層級。 LogLevel 表示記錄的嚴重性,範圍從 0 到 6:

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

指定 LogLevel 時,會針對指定層級和更高層級的訊息啟用記錄。 在上述 JSON 中,Default 類別會記錄為 Information 和更新版本。 例如,會記錄 InformationWarningErrorCritical 訊息。 如果未指定 LogLevel,則記錄預設為 Information 層級。 如需詳細資訊,請參閱記錄層級

提供者屬性可以指定 LogLevel 屬性。 LogLevel 在提供者下,會指定要針對該提供者記錄的層級,並覆寫非提供者記錄設定。 請考量下列 appsettings.json 檔案:

{
  "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 中的設定。 在上述 JSON 中,Debug 提供者的預設記錄層級會設定為 Information

Logging:Debug:LogLevel:Default:Information

上述設定會指定每個 Logging:Debug: 類別的 Information 記錄層級,但 Microsoft.Hosting 除外。 列出特定類別時,特定類別會覆寫預設類別。 在上述 JSON 中,Logging:Debug:LogLevel 類別 "Microsoft.Hosting""Default" 會覆寫 Logging:LogLevel 中的設定

您可以針對下列任一項目指定最小記錄層級:

  • 特定提供者:例如 Logging:EventSource:LogLevel:Default:Information
  • 特定類別:例如 Logging:LogLevel:Microsoft:Warning
  • 所有提供者和所有類別:Logging:LogLevel:Default:Warning

低於最低層級的任何記錄都不是

  • 傳遞至提供者。
  • 已記錄或顯示。

若要隱藏所有記錄,請指定 LogLevel.NoneLogLevel.None 的值為 6,其高於 LogLevel.Critical (5)。

若提供者支援記錄範圍IncludeScopes 會指出是否已啟用記錄範圍。 如需詳細資訊,請參閱記錄範圍

下列 appsettings.json 檔案包含預設啟用的所有提供者:

{
  "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"
      }
    }
  }
}

在上述範例中:

  • 類別和層級不是建議的值。 會提供此範例以顯示所有的預設提供者。
  • Logging.{providername}.LogLevel 中的設定會覆寫 Logging.LogLevel 中的設定。 例如,Debug.LogLevel.Default 中的層級會覆寫 LogLevel.Default 中的層級。
  • 會使用每個預設提供者「別名」。 每個提供者都會定義「別名」,可在設定中用來取代完整類型名稱。 內建提供者別名如下:
    • 主控台
    • 偵錯
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

依命令列、環境變數和其他組態設定記錄層級

記錄層級可由任何設定提供者進行設定。

: 分隔符號不適用於所有平台上的環境變數階層式機碼。 __,雙底線,為:

  • 所有平台都支援。 例如,Bash 不支援 : 分隔符號,但支援 __
  • 自動由 : 取代

下列 命令:

  • 將環境索引鍵 Logging:LogLevel:Microsoft 設定為 Windows 上的 Information 值。
  • 使用搭配 ASP.NET Core Web 應用程式範本建立的應用程式時,請測試設定。 在使用 set 之後,必須在專案目錄中執行 dotnet run 命令。
set Logging__LogLevel__Microsoft=Information
dotnet run

上述環境設定:

  • 只會在從其所設定命令視窗啟動的程序中進行設定。
  • 不會由使用 Visual Studio 啟動的瀏覽器讀取。

下列 setx 命令也會設定 Windows 上的環境索引鍵和值。 不同於 setsetx 設定會予以保存。 /M 參數會在系統內容中設定變數。 如果未使用 /M,則會設定使用者環境變數。

setx Logging__LogLevel__Microsoft Information /M

請考量下列 appsettings.json 檔案:

"Logging": {
    "Console": {
      "LogLevel": {
        "Microsoft.Hosting.Lifetime": "Trace"
      }
    }
}

下列命令會在環境中設定上述組態:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Azure App Service 上,選取 [設定] > [組態] 頁面上的 [新增應用程式設定]。 Azure App Service 應用程式設定為:

  • 在待用及透過加密通道傳輸時加密。
  • 公開為環境變數。

如需詳細資訊,請參閱 Azure App:使用 Azure 入口網站覆寫應用程式設定

如需使用環境變數設定 ASP.NET Core 組態值的詳細資訊,請參閱環境變數。 如需使用其他組態來源 (包括命令列、Azure Key Vault、Azure 應用程式組態、其他檔案格式等等) 的相關資訊,請參閱 ASP.NET Core 的設定

如何套用篩選規則

建立 ILogger<TCategoryName> 物件時,ILoggerFactory 物件會針對每個提供者選取一個規則來套用到該記錄器。 由 ILogger 執行個體寫入的所有訊息都會根據選取的規則進行篩選。 系統會從可用的規則中,選取對每個提供者和類別配對最明確的規則。

當建立指定類別的 ILogger 時,系統會針對每個提供者使用下列演算法:

  • 選取所有符合提供者或其別名的規則。 如果找不到符合的項目,請選取所有規則搭配空白提供者。
  • 從上一個步驟的結果中,選取具有最長相符類別前置字元的規則。 如果找不到符合的項目,請選取未指定類別的所有規則。
  • 如果選取多個規則,請使用最後一個。
  • 如果未選取任何規則,請使用 MinimumLevel

記錄 dotnet run 和 Visual Studio 的輸出

使用預設記錄提供者建立的記錄會顯示:

  • 在 Visual Studio 中
    • 在 [偵錯輸出] 視窗中 (偵錯時)。
    • 在 [ASP.NET Core Web 伺服器] 視窗中。
  • 在主控台視窗中 (使用 dotnet run 執行應用程式時)。

開頭為 "Microsoft" 類別的記錄則是來自 ASP.NET Core 架構程式碼。 ASP.NET Core 與應用程式程式碼會使用相同的記錄 API 與提供者。

記錄類別

建立 ILogger 物件時,會指定「類別」。 該類別會包含在每個由該 ILogger 執行個體所產生的記錄訊息中。 類別字串為任意值,但慣例是使用類別名稱。 例如,在控制器中,名稱可能是 "TodoApi.Controllers.TodoController"。 ASP.NET Core Web 應用程式會使用 ILogger<T> 來自動取得 ILogger 執行個體,該執行個體會使用 T 的完整類型名稱來做為類別:

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

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

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

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

在多個方法中使用時,以固定名稱呼叫 CreateLogger 可能會很有用,因此可依類別來組織事件。

ILogger<T> 相當於使用 T的完整類型名稱來呼叫 CreateLogger

記錄等級

下表列出 LogLevel 值、便利的 Log{LogLevel} 擴充方法和建議的使用方式:

LogLevel 方法 描述
追蹤 0 LogTrace 包含最詳細的訊息。 這些訊息可能包含敏感性應用程式資料。 這些訊息預設會停用,且應在生產環境中啟用。
偵錯 1 LogDebug 用於偵錯和開發。 由於大量,因此在生產環境中請謹慎使用。
資訊 2 LogInformation 追蹤一般應用程式流程。 可能具有長期值。
警告 3 LogWarning 針對異常或意外事件。 通常包含不會導致應用程式失敗的錯誤或狀況。
錯誤 4 LogError 發生無法處理的錯誤和例外狀況。 這些訊息指出目前作業或要求中發生失敗,而不是整個應用程式的失敗。
重大 5 LogCritical 發生需要立即注意的失敗。 範例:資料遺失情況、磁碟空間不足。
None 6 指定記錄類別不應寫入任何訊息。

在上表中,會從最低到最高嚴重性列出 LogLevel

Log 方法的第一個參數 (LogLevel) 表示記錄的嚴重性。 大部分開發人員會呼叫 Log{LogLevel} 擴充方法,而不是呼叫 Log(LogLevel, ...)Log{LogLevel} 擴充方法會呼叫 Log 方法,並指定 LogLevel。 例如,下列兩個記錄呼叫在功能上相等,並產生相同的記錄:

[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 為事件識別碼。 MyLogEvents 是範例應用程式的一部分,且會顯示在記錄事件識別碼區段中。

MyDisplayRouteInfo 和 ToCtxString 是由 Rick.Docs.Samples.RouteInfo NuGet 套件提供。 方法會顯示 ControllerRazor Page 路由資訊。

下列程式碼會建立 InformationWarning 記錄:

[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) 是記錄事件識別碼。 第二個參數是訊息範本,其中的預留位置會置入其餘方法參數所提供的引數值。 此文件稍後的訊息範本小節將詳細說明方法參數。

呼叫適當的 Log{LogLevel} 方法來控制要寫入至特定儲存媒體的記錄輸出量。 例如:

  • 生產環境:
    • TraceInformation 層級的記錄會產生大量的詳細記錄訊息。 若要控制成本,且不超過資料儲存體限制,請將 TraceInformation 層級訊息記錄為大量、低成本的資料存放區。 請考慮將 TraceInformation 限制為特定類別。
    • 透過 Critical 層級的 Warning 記錄應該會產生一些記錄訊息。
      • 成本和儲存體限制通常無所謂。
      • 記錄數少可讓資料存放區選擇更具彈性。
  • 開發中:
    • 設定為 Warning
    • 進行疑難排解時,新增 TraceInformation 訊息。 若要限制輸出,請僅針對調查中的類別設定 TraceInformation

ASP.NET Core 會寫入架構事件的記錄。 例如,請考慮下列項目的記錄輸出:

  • 使用 ASP.NET Core 範本建立的 Razor Pages 應用程式。
  • 記錄設定為 Logging:Console:LogLevel:Microsoft:Information
  • 瀏覽至 Privacy 頁面:
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:Information

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

記錄事件識別碼

每個記錄都可以指定「事件識別碼」。 範例應用程式會使用 MyLogEvents 類別來定義事件識別碼:

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

事件識別碼會將一組事件關聯。 例如,與在頁面上顯示項目清單相關的所有記錄可能都是 1001。

記錄提供者可能將事件識別碼存放到識別碼欄位、記錄訊息中或完全不存放。 偵錯提供者不會顯示事件識別碼。 主控台提供者會在類別後面以括弧顯示事件識別碼:

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

有些記錄提供者會將事件識別碼儲存在欄位中,以允許篩選識別碼。

記錄訊息範本

每個記錄 API 都會使用訊息範本。 訊息範本可以包含有關提供哪個引數的預留位置。 使用名稱而非數字做為預留位置。

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

參數的順序 (而不是其預留位置名稱) 會決定哪些參數可用來在記錄訊息中提供預留位置值。 在下列程式碼中,參數名稱在訊息範本的預留位置中未依順序出現:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

不過,參數會依序指派給預留位置:applespearsbananas。 記錄訊息會反映「參數的順序」

Parameters: 1, 2, 3

此方法可讓記錄提供者實作語意或結構化記錄。 引數本身會被傳遞到記錄系統,而不只是格式化的訊息範本。 這可讓記錄提供者將參數值儲存為欄位。 例如,請考量下列記錄器方法:

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

例如,登入 Azure 資料表儲存體時:

  • 每個 Azure 資料表實體都可以有 IDRequestTime 屬性。
  • 具有屬性的資料表可簡化針對記錄資料的查詢。 例如,查詢可以尋找特定 RequestTime 範圍內的所有記錄,而不必剖析文字訊息中的時間。

記錄例外狀況

記錄器方法具有多載可接受例外狀況參數:

[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 和 ToCtxString 是由 Rick.Docs.Samples.RouteInfo NuGet 套件提供。 方法會顯示 ControllerRazor Page 路由資訊。

例外狀況記錄是提供者特定的。

預設記錄層級

如果未設定預設記錄層級,則預設記錄層級值為 Information

例如,請考量下列 Web 應用程式:

  • 使用 ASP.NET Web 應用程式範本所建立。
  • appsettings.jsonappsettings.Development.json 已刪除或重新命名。

在上述設定中,瀏覽至隱私權或首頁會產生許多類別名稱中具有 MicrosoftTraceDebugInformation 訊息。

下列程式碼會在設定中未設定預設記錄層級時,設定預設記錄層級:

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

一般而言,應該在組態而不是程式碼中指定記錄層級。

Filter 函式

針對組態或程式碼未指派規則的所有提供者和類別,會叫用篩選函式:

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 或更高層級時顯示主控台記錄。

一般而言,應該在組態而不是程式碼中指定記錄層級。

ASP.NET Core 和 EF Core 類別

下表包含 ASP.NET Core 和 Entity Framework Core 所使用的一些類別,以及記錄的相關注意事項:

類別 備註
Microsoft.AspNetCore 一般 ASP.NET Core 診斷。
Microsoft.AspNetCore.DataProtection 已考慮、發現及使用哪些金鑰。
Microsoft.AspNetCore.HostFiltering 允許主機。
Microsoft.AspNetCore.Hosting HTTP 要求花了多少時間完成,以及其開始時間。 載入了哪些裝載啟動組件。
Microsoft.AspNetCore.Mvc MVC 和 Razor 診斷。 模型繫結、篩選執行、檢視編譯、動作選取。
Microsoft.AspNetCore.Routing 路由比對資訊。
Microsoft.AspNetCore.Server 連線開始、停止與保持運作回應。 HTTPS 憑證資訊。
Microsoft.AspNetCore.StaticFiles 提供的檔案。
Microsoft.EntityFrameworkCore 一般 Entity Framework Core 診斷。 資料庫活動與設定、變更偵測、移轉。

若要在主控台視窗中檢視更多類別,請將 appsettings.Development.json 設定為下列項目:

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

記錄範圍

「範圍」可用來將邏輯作業組成群組。 此分組功能可用來將相同的資料附加到已建立為集合之一部分的每個記錄。 例如,在處理邀交易時建立的每個記錄都可以包括該交易識別碼。

範圍:

下列提供者支援範圍:

透過將記錄器呼叫封裝在 using 區塊中以使用範圍:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _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);
}

內建記錄提供者

ASP.NET Core 包含下列記錄提供者做為共用架構的一部分:

下列記錄提供者是由 Microsoft 提供,但不是共用架構的一部分。 必須將其安裝做為額外的 NuGet。

ASP.NET Core 不包含記錄提供者,可用來將記錄寫入檔案。 若要從 ASP.NET Core 應用程式將記錄寫入檔案,請考慮使用協力廠商記錄提供者

如需使用 ASP.NET Core 模組進行 stdout 和偵錯記錄的相關資訊,請參閱針對 Azure App Service 上的 ASP.NET Core 進行疑難排解,以及 ASP.NET Core Module (ANCM) for IIS

主控台

Console 提供者會將輸出記錄到主控台。 如需在開發中檢視 Console 記錄的相關詳細資訊,請參閱記錄 dotnet run 和 Visual Studio 的輸出

偵錯

Debug 提供者會使用 System.Diagnostics.Debug 類別來寫入記錄輸出。 呼叫 System.Diagnostics.Debug.WriteLine 寫入 Debug 提供者。

在 Linux 上,Debug 提供者記錄位置與散發相依,可能是下列其中一項:

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

事件來源

EventSource 提供者會寫入名稱為 Microsoft-Extensions-Logging 的跨平台事件來源。 在 Windows 上,提供者會使用 ETW

dotnet 追蹤工具

dotnet-trace 工具是一種跨平台 CLI 全域工具,可收集執行中程序的 .NET Core 追蹤。 此工具會使用 LoggingEventSource 收集 Microsoft.Extensions.Logging.EventSource 提供者資料。

如需安裝指示,請參閱 dotnet-trace

使用 dotnet 追蹤工具從應用程式收集追蹤:

  1. 使用 dotnet run 命令執行應用程式。

  2. 判斷 .NET Core 應用程式的程序識別碼 (PID):

    dotnet trace ps
    

    尋找與應用程式元件名稱相同程序的 PID。

  3. 執行 dotnet trace 命令。

    一般命令語法:

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

    使用 PowerShell 命令殼層時,以單引號括住 --providers 值 ('):

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

    在非 Windows 平台上,新增 -f speedscope 選項,將輸出追蹤檔案的格式變更為 speedscope

    下表會定義關鍵字:

    關鍵字 描述
    1 記錄有關 LoggingEventSource 的中繼事件。 不會記錄來自 ILogger 的事件。
    2 呼叫 ILogger.Log() 時,開啟 Message。 以程式設計 (而非格式化) 的方式提供資訊。
    4 呼叫 ILogger.Log() 時,開啟 FormatMessage。 提供資訊的格式化字串版本。
    8 呼叫 ILogger.Log() 時,開啟 MessageJson。 提供引數的 JSON 表示法。

    下表列出提供者層級:

    提供者層級 描述
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    類別層級的剖析可以是字串或數字:

    類別具名值 數值
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    提供者層級和類別層級:

    • 是反向順序。
    • 字串常數不完全相同。

    如果未指定 FilterSpecs,則 EventSourceLogger 實作會嘗試將提供者層級轉換成類別層級,並將其套用至所有類別。

    提供者層級 類別層級
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    如果已提供 FilterSpecs,則清單中所包含的任何類別都會使用在該處編碼的類別層級,並會篩選掉所有其他類別。

    下列範例假設:

    • 應用程式正在執行並呼叫 logger.LogDebug("12345")
    • 已透過 set PID=12345 設定程序識別碼 (PID),其中 12345 是實際的 PID。

    請考慮下列命令:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    上述命令會:

    • 擷取偵錯訊息。
    • 不會套用 FilterSpecs
    • 指定層級 5,其可對應類別偵錯。

    請考慮下列命令:

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    上述命令會:

    • 不會擷取偵錯訊息,因為類別層級 5 是 Critical
    • 可提供 FilterSpecs

    下列命令會擷取偵錯訊息,因為類別層級 1 指定 Debug

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    下列命令會擷取偵錯訊息,因為類別指定 Debug

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    {Logger Category}{Category Level}FilterSpecs 代表其他記錄篩選條件。 以 ; 分號字元分隔 FilterSpecs 項目。

    使用 Windows 命令殼層的範例:

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

    上述命令會啟動︰

    • 事件來源記錄器,可針對錯誤 (2) 產生格式化字串 (4)。
    • Informational 記錄層級 (4) 的 Microsoft.AspNetCore.Hosting 記錄。
  4. 按下 Enter 鍵或 Ctrl+C 以停止 dotnet 追蹤工具。

    追蹤會以 trace.nettrace 名稱儲存在執行 dotnet trace 命令的資料夾中。

  5. 使用 Perfview 開啟追蹤。 開啟 trace.nettrace 檔案並探索追蹤事件。

如果應用程式未使用 CreateDefaultBuilder 建置主機,請將事件來源提供者新增至應用程式的記錄設定。

如需詳細資訊,請參閱

Perfview

使用 PerfView 公用程式來收集和檢視記錄。 此外還有一些其他工具可檢視 ETW 記錄,但 PerfView 提供處理 ASP.NET Core 所發出 ETW 事件的最佳體驗。

若要設定 PerfView 以收集此提供者所記錄的事件,請將字串 *Microsoft-Extensions-Logging 新增至 [其他提供者] 清單 請勿遺漏字串開頭的 *

Windows EventLog

EventLog 提供者會將記錄輸出傳送至 Windows 事件記錄檔。 與其他提供者不同,EventLog 提供者不會繼承預設的非提供者設定。 如果未指定 EventLog 記錄設定,則預設為 LogLevel.Warning

若要記錄低於 LogLevel.Warning 的事件,請明確設定記錄層級。 下列範例會將事件記錄檔預設記錄層級設定為 LogLevel.Information

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

AddEventLog 多載 可傳入 EventLogSettings。 如果 null 或未指定,則會使用下列預設設定:

  • LogName:「應用程式」
  • SourceName:「.NET Runtime」
  • MachineName:使用本機電腦名稱。

下列程式碼會將 SourceName".NET Runtime" 的預設值變更為 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 App Service

Microsoft.Extensions.Logging.AzureAppServices 提供者套件會將記錄寫入至 Azure App Service 應用程式檔案系統中的文字檔,並寫入至 Azure 儲存體帳戶中的 Blob 儲存體

該提供者套件並未包含在共用架構中。 若要使用提供者,請將提供者套件新增至專案。

如果要進行提供者設定,請使用 AzureFileLoggerOptionsAzureBlobLoggerOptions,如以下範例中所示:

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 App Service 時,應用程式會使用 Azure 入口網站 [App Service] 頁面中 App Service 記錄區段的設定。 當下列設定更新時,變更會立即生效,而不需要重新啟動或重新部署應用程式。

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

記錄檔的預設位置為 D:\home\LogFiles\Application 資料夾,而預設檔案名稱為 diagnostics-yyyymmdd.txt。 預設檔案大小限制為 10 MB,而預設保留的檔案數目上限為 2。 預設 Blob 名稱為 {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt

此提供者僅記錄專案在 Azure 環境中執行的情況。

Azure 記錄串流

Azure 記錄串流可支援即時檢視來自下列位置的記錄活動:

  • 應用程式伺服器
  • 網頁伺服器
  • 失敗要求的追蹤

若要設定 Azure 記錄資料流:

  • 從應用程式的入口網站頁面瀏覽到 [App Service 記錄]
  • 將 [應用程式記錄 (檔案系統)] 設定為 [開啟]
  • 選擇記錄 [層級]。 此設定僅適用於 Azure 記錄串流。

瀏覽到 [記錄資料流] 頁面以檢視記錄。 記錄的訊息會與 ILogger 介面一起記錄。

Azure Application Insights

Microsoft.Extensions.Logging.ApplicationInsights 提供者套件會將記錄寫入至 Azure Application Insights。 Application Insights 是可監視 Web 應用程式的服務,並提供可用來查詢及分析遙測資料的工具。 如果您使用此提供者,就可以使用 Application Insights 工具來查詢及分析記錄。

記錄提供者會以 Microsoft.ApplicationInsights.AspNetCore \(英文\) 的相依性形式隨附,這是針對 ASP.NET Core 提供所有可用遙測的套件。 如果您使用此套件,就不需安裝提供者套件。

Microsoft.ApplicationInsights.Web 套件適用於 ASP.NET 4.x,而不適用於 ASP.NET Core。

如需詳細資訊,請參閱以下資源:

協力廠商記錄提供者

可搭配 ASP.NET Core 使用的協力廠商記錄架構:

某些協力廠商架構可以執行語意記錄 (也稱為結構化記錄) \(英文\)。

使用協力廠商架構類似於使用內建的提供者之一:

  1. 將 NuGet 套件新增至專案。
  2. 呼叫記錄架構所提供的 ILoggerFactory 擴充方法。

如需詳細資訊,請參閱每個提供者的文件。 Microsoft 不支援第三方記錄提供者。

非主機主控台應用程式

如需如何在非 Web 主控台應用程式中使用一般主機的範例,請參閱背景工作範例應用程式 (在 ASP.NET Core 中使用託管服務的背景工作) 的 Program.cs 檔案。

不含一般主機的應用程式記錄程式碼,會因新增提供者和建立記錄器的方式而有所不同。

記錄提供者

在非主機主控台應用程式中,於建立 LoggerFactory 時呼叫提供者的 Add{provider name} 擴充方法:

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

建立記錄

若要建立記錄,請使用 ILogger<TCategoryName> 物件。 使用 LoggerFactory 來建立 ILogger

下列範例會建立以 LoggingConsoleApp.Program 做為類別的記錄器。

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

在下列範例中,記錄器會用於以 Information 做為層級來建立記錄。 記錄「層級」 指出已記錄事件的嚴重性。

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

此文件將詳細說明層級類別

主機建構期間的記錄

不直接支援在主機建構期間進行記錄。 不過,可以使用個別的記錄器。 在下列範例中,會使用 Serilog 記錄器來記錄 CreateHostBuilderAddSerilog 會使用 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 的服務

記錄器的建構函式插入 Startup 適用於舊版 ASP.NET Core,因為會為 Web 主機建立個別的 DI 容器。 如需為何只為一般主機建立一個容器的資訊,請參閱重大變更公告

若要設定相依於 ILogger<T> 的服務,請使用建構函式插入或提供 Factory 方法。 只有在沒有其他選項時,才建議使用 Factory 方法。 例如,請考慮需要 ILogger<T> 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<T,TResult>,會在 DI 容器第一次需要建立 MyService 的執行個體時執行。 您可以用此方式存取任何已註冊的服務。

在 Main 中建立記錄

下列程式碼會藉由在建置主機之後,從 DI 取得 Main 執行個體來登入 ILogger

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

在啟動中建立記錄

下列程式碼會將記錄寫入在 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 容器設定之前,不支援寫入記錄檔:

  • 不支援將記錄器插入 Startup 建構函式。
  • 不支援將記錄器插入 Startup.ConfigureServices 方法簽章

這項限制的原因是記錄相依於 DI 和組態,而後者相依於 DI。 在 ConfigureServices 完成後才會設定 DI 容器。

如需設定相依於 ILogger<T> 的服務,或為何將記錄器的建構函式插入在舊版中運作 Startup 的相關資訊,請參閱設定相依於 ILogger 的服務

無非同步記錄器方法

記錄速度應該很快,不值得花費非同步程式碼的效能成本來處理。 若記錄資料存放區很慢,請不要直接寫入其中。 請考慮一開始將記錄寫入到快速的存放區,稍後再將其移到慢速存放區。 例如,當記錄到 SQL Server 時,請勿在 Log 方法中直接執行,因為 Log 方法是同步的。 相反地,以同步方式將記錄訊息新增到記憶體內佇列,並讓背景工作角色提取出佇列的訊息,藉此執行推送資料到 SQL Server 的非同步工作。 如需詳細資訊,請參閱這個 GitHub 問題。

變更執行中應用程式的記錄層級

記錄 API 不包含應用程式執行時變更記錄層級的案例。 不過,某些組態提供者能夠重新載入組態,這會立即對記錄組態生效。 例如,檔案組態提供者預設會重新載入記錄組態。 如果應用程式執行時在程式碼中變更組態,則應用程式可以呼叫 IConfigurationRoot.Reload 來更新應用程式的記錄組態。

ILogger 和 ILoggerFactory

ILogger<TCategoryName>ILoggerFactory 介面及實作會包含在 .NET Core SDK 中。 其也可以在下列 NuGet 套件中使用:

在程式碼中套用記錄篩選規則

設定記錄篩選規則的慣用方法是使用組態

下列範例說明如何在程式碼中註冊篩選規則:

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 類別和記錄層級 Debug。 篩選條件會套用至所有提供者,因為未設定特定提供者。

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) 會指定:

  • Debug 記錄提供者。
  • 記錄層級 Information 和更新版本。
  • "Microsoft" 開始的所有類別。

使用 SpanId、TraceId 和 ParentId 自動記錄範圍

記錄程式庫會隱含地使用 SpanIdTraceIdParentId 來建立範圍物件。 此行為是透過 ActivityTrackingOptions 進行設定。

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

如果已設定 traceparent http 要求標頭,則記錄範圍中的 ParentId 會顯示來自輸入 traceparent 標頭的 W3C parent-id,而記錄範圍中的 SpanId 會顯示下一個輸出步驟/範圍的更新 parent-id。 如需詳細資訊,請參閱變動 traceparent 欄位

建立自訂記錄器

若要建立自訂記錄器,請參閱在 .NET 中實作自訂記錄提供者

其他資源