.NET Core および ASP.NET Core でのログ記録
Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
作成者: Kirk Larkin、Juergen Gutsch、Rick Anderson
この記事では、ASP.NET Core アプリに適用される .NET のログについて説明します。 .NET のログの詳細については、「.NET でのログの記録」を参照してください。
このノードのガイダンスを追加または置き換える Blazor ログのガイダンスについては、「ASP.NET Core Blazor のログ」をご覧ください。
ログ プロバイダー
ログを表示する Console
プロバイダーを除き、ログ プロバイダーはログを保存します。 たとえば、Azure Application Insights プロバイダーでは、Azure Application Insights にログが保存されます。 複数のプロバイダーを有効にすることができます。
既定の ASP.NET Core Web アプリ テンプレートからは WebApplication.CreateBuilder が呼び出されます。これにより、次のログ プロバイダーが追加されます。
- コンソール
- デバッグ
- EventSource
- EventLog:Windows のみ
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();
});
その他のプロバイダーについては、以下を参照してください。
ログを作成する
ログを作成するには、依存関係の挿入 (DI) から ILogger<TCategoryName> オブジェクトを使用します。
次のような例です。
AboutModel
型の完全修飾名のログ "カテゴリ" を使用する、ロガーILogger<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 Core Blazor のログ」をご覧ください。
ログの構成
一般に、ログの構成は appsettings.{ENVIRONMENT}.json
ファイルの Logging
セクションに記述されます。{ENVIRONMENT}
は、環境を表すプレースホルダーです。 ASP.NET Core の Web アプリ テンプレートによって、次の appsettings.Development.json
ファイルが生成されます。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
上記の JSON では、次のように指定されています。
"Default"
および"Microsoft.AspNetCore"
の各カテゴリが指定されています。"Microsoft.AspNetCore"
カテゴリは、"Microsoft.AspNetCore"
で始まるすべてのカテゴリに適用されます。 たとえば、この設定は"Microsoft.AspNetCore.Routing.EndpointMiddleware"
カテゴリに適用されます。"Microsoft.AspNetCore"
カテゴリでは、ログ レベルがWarning
以上のログが記録されます。- 特定のログ プロバイダーが指定されていないため、
LogLevel
は、Windows EventLog を除くすべての有効なログ プロバイダーに適用されます。
Logging
プロパティには LogLevel およびログ プロバイダーのプロパティを含めることができます。 LogLevel
により、選択したカテゴリに対するログの最小レベルが指定されます。 上記の JSON では、Information
と Warning
のログ レベルが指定されています。 LogLevel
はログの重大度を 0 - 6 の範囲で示します。
Trace
= 0、Debug
= 1、Information
= 2、Warning
= 3、Error
= 4、Critical
= 5、None
= 6。
LogLevel
を指定すると、指定したレベル以上のメッセージに対してログが有効になります。 上記の JSON では、Default
カテゴリは Information
以上に対してのみログに記録されます。 たとえば、Information
、Warning
、Error
、Critical
のメッセージがログに記録されます。 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.LogLevel
の設定は、Logging.{PROVIDER NAME}.LogLevel
の設定によってオーバーライドされます。{PROVIDER NAME}
は、プロバイダーの名前を表すプレースホルダーです。 上記の JSON では、Debug
プロバイダーの既定のログ レベルは Information
に設定されています。
Logging:Debug:LogLevel:Default:Information
上記の設定により、Microsoft.Hosting
以外のすべての Logging:Debug:
カテゴリに Information
ログ レベルが指定されます。 特定のカテゴリが一覧表示されると、特定のカテゴリによって既定のカテゴリがオーバーライドされます。 上記の JSON では、Logging:Debug:LogLevel
カテゴリ "Microsoft.Hosting"
と "Default"
によって、Logging:LogLevel
の設定がオーバーライドされます。
最小ログ レベルは、次のいずれかに指定できます。
- 特定のプロバイダー: たとえば、
Logging:EventSource:LogLevel:Default:Information
- 特定のカテゴリ: たとえば、
Logging:LogLevel:Microsoft:Warning
- すべてのプロバイダーとすべてのカテゴリ:
Logging:LogLevel:Default:Warning
最小レベルを下回るログは、次のことが "行われません"。
- プロバイダーに渡される。
- ログに記録または表示される。
ログをすべて抑制するには LogLevel.None を指定します。 LogLevel.None
の値は、LogLevel.Critical
(5) より大きい 6 です。
プロバイダーでログのスコープがサポートされている場合、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.LogLevel
の設定は、Logging.{PROVIDER NAME}.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 アプリケーション テンプレートを使用して作成されたアプリを使用する際に、設定をテストします。
dotnet run
コマンドは、set
を使用した後、プロジェクト ディレクトリで実行する必要があります。
set Logging__LogLevel__Microsoft=Information
dotnet run
上記の環境設定は:
- コマンド ウィンドウから起動されたプロセスでのみ設定可能です。
- Visual Studio で起動されたブラウザーでは読み取れません。
次の setx コマンドは、Windows 上で環境キーと値も設定します。 set
とは異なり、setx
設定は保持されます。 /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
Note
macOS と Linux で .
(ピリオド) を含む名前で環境変数を構成する場合は、Stack Exchange の「ドット (.) が含まれる変数のエクスポート」という質問と、それに対して受け入れられた回答を考慮してください。
Azure App Service の、[設定] > [構成] ページで [新しいアプリケーション設定] を選択します。 Azure App Service アプリケーションの設定は:
- rest に暗号化され、暗号化されたチャネルで送信されます。
- 環境変数として公開されます。
詳細については、Azure アプリの、Azure portal を使ったアプリの構成のオーバーライドに関する記事を参照してください。
環境変数を使用して ASP.NET Core 構成値を設定する方法の詳細については、「環境変数」を参照してください。 コマンド ライン、Azure Key Vault、Azure App Configuration、その他のファイル形式など、他の構成ソースの使用の詳細については、「ASP.NET Core の構成」を参照してください。
フィルター規則を適用する方法
ILogger<TCategoryName> オブジェクトを作成すると、ILoggerFactory オブジェクトによって、そのロガーに適用するプロバイダーごとに 1 つの規則が選択されます。 ILogger
インスタンスによって書き込まれるすべてのメッセージは、選択した規則に基づいてフィルター処理されます。 使用できる規則から、各プロバイダーとカテゴリのペアごとに最も明確な規則が選択されます。
特定のカテゴリに ILogger
が作成されるときに、各プロバイダーに次のアルゴリズムが使用されます。
- プロバイダーとそのエイリアスと一致するすべての規則が選択されます。 一致が見つからない場合は、空のプロバイダーですべての規則が選択されます。
- 前の手順の結果、最も長いカテゴリのプレフィックスが一致する規則が選択されます。 一致が見つからない場合は、カテゴリを指定しないすべての規則が選択されます。
- 複数の規則が選択されている場合は、最後の 1 つが使用されます。
- 規則が選択されていない場合は、
MinimumLevel
が使用されます。
dotnet run および Visual Studio からのログ出力
既定のログ プロバイダーで作成されたログが表示されます。
- Visual Studio 内
- デバッグ時はデバッグ出力ウィンドウ内。
- ASP.NET Core Web サーバー ウィンドウ内。
- アプリが
dotnet run
で実行されている場合はコンソール ウィンドウ内。
"Microsoft" カテゴリから始まるログは、.NET のログです。 .NET とアプリケーション コードでは、同じログ API とログ プロバイダーが使用されます。
ログのカテゴリ
ILogger
オブジェクトが作成されるときに、"カテゴリ" が指定されます。 このカテゴリは、ILogger
のインスタンスによって作成される各ログ メッセージと共に含められます。 カテゴリ文字列は任意ですが、慣習的には完全修飾クラス名を使用します。 たとえば、コントローラーでは、名前が "TodoApi.Controllers.TodoController"
になる場合があります。 ASP.NET Core Web アプリでは、ILogger<T>
を使用して、カテゴリとして T
の完全修飾型名を使用する ILogger
インスタンスが自動的に取得されます。
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 | [値] | Method | 説明 |
---|---|---|---|
Trace | 0 | LogTrace | 最も詳細なメッセージが含まれます。 これらのメッセージには、機密性の高いアプリ データが含まれる場合があります。 これらのメッセージは既定で無効になっているため、運用環境では有効に "しないでください"。 |
Debug | 1 | LogDebug | デバッグと開発用。 量が多いため、運用環境では慎重に使用してください。 |
Information | 2 | LogInformation | アプリの一般的なフローを追跡します。 長期的な値が含まれている可能性があります。 |
Warning | 3 | LogWarning | 異常なイベントや予期しないイベント用。 通常、アプリが失敗する原因にならないエラーや条件が含まれます。 |
Error | 4 | LogError | 処理できないエラーと例外の場合。 これらのメッセージは、アプリ全体のエラーではなく、現在の操作や要求における失敗を示します。 |
Critical | 5 | LogCritical | 即時の注意が必要なエラーの場合。 例: データ損失のシナリオ、ディスク領域不足。 |
None | 6 | ログのカテゴリにメッセージを出力しないように指定します。 |
前の表では、重大度が最も低い方から高い方に LogLevel
が一覧表示されています。
Log メソッドの最初のパラメーター LogLevel は、ログの重大度を示します。 ほとんどの開発者は、Log(LogLevel, ...)
を呼び出すのではなく、Log{LOG LEVEL}
拡張メソッドを呼び出します。{LOG LEVEL}
は、ログ レベルを表すプレースホルダーです。 たとえば、次の 2 つのログ呼び出しは、機能的に同等で、同じログが生成されます。
[HttpGet]
public IActionResult Test1(int id)
{
var routeInfo = ControllerContext.ToCtxString(id);
_logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
_logger.LogInformation(MyLogEvents.TestItem, routeInfo);
return ControllerContext.MyDisplayRouteInfo();
}
MyLogEvents.TestItem
はイベント ID です。 MyLogEvents
はサンプル アプリの一部であり、ログ イベント ID セクションに表示されます。
MyDisplayRouteInfo and ToCtxString は Rick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller
および Razor Page
ルート情報が表示されます。
Information
および Warning
ログを作成するコードを次に示します。
[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
は、ログ イベント ID です。 2 つ目のパラメーターは、他のメソッド パラメーターによって提供される引数値のプレースホルダーを含むメッセージ テンプレートです。 メソッド パラメーターについては、このドキュメントで後述するメッセージ テンプレートのセクションで説明します。
適切な Log{LOG LEVEL}
メソッドを呼び出して、特定のストレージ メディアに書き込むログ出力量を制御します。 次に例を示します。
- 運用環境:
Trace
、Debug
、またはInformation
のレベルでログすると、詳細なログ メッセージが大量に生成されます。 コストを制御し、データ ストレージの上限を超えないようにするには、Trace
、Debug
、またはInformation
のレベルのメッセージを、大容量の低コストのデータ ストアにログします。Trace
、Debug
、Information
を特定のカテゴリに制限することを検討してください。Warning
からCritical
のレベルでログを記録しても、ログ メッセージはほとんど生成されません。- 通常、コストとストレージの制限は考慮されません。
- ログの数が少ないほど、データ ストアをより柔軟に選択できるようになります。
- 開発中:
Warning
に設定します。- トラブルシューティングの際に
Trace
、Debug
、またはInformation
のメッセージを追加します。 出力を制限するには、調査中のカテゴリに対してのみTrace
、Debug
、またはInformation
を設定します。
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"
}
}
}
}
ログ イベント ID
各ログで "イベント ID" を指定できます。 このサンプル アプリでは、MyLogEvents
クラスを使用してイベント ID を定義します。
public class MyLogEvents
{
public const int GenerateItems = 1000;
public const int ListItems = 1001;
public const int GetItem = 1002;
public const int InsertItem = 1003;
public const int UpdateItem = 1004;
public const int DeleteItem = 1005;
public const int TestItem = 3000;
public const int GetItemNotFound = 4000;
public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
_logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
_logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
return NotFound();
}
return ItemToDTO(todoItem);
}
イベント ID によって一連のイベントが関連付けられます。 たとえば、ページ上に項目の一覧を表示する機能に関連するすべてのログを 1001 に設定します。
ログ プロバイダーでは、ID フィールドやログ メッセージにイベント ID が格納されたり、またはまったく格納されなかったりする場合があります。 Debug プロバイダーでイベント ID が表示されることはありません。 Console プロバイダーでは、カテゴリの後のブラケット内にイベント ID が表示されます。
info: TodoApi.Controllers.TodoItemsController[1002]
Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
Get(1) NOT FOUND
一部のログ プロバイダーでは、イベント ID がフィールドに格納されます。これにより、ID に対するフィルター処理が可能になります。
ログ メッセージ テンプレート
各ログ 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);
しかし、プレースホルダーには、apples
、pears
、bananas
という順序でパラメーターが割り当てられます。 ログ メッセージに、パラメーターの順序が反映されています。
Parameters: 1, 2, 3
この方法により、ログ プロバイダーが セマンティック ログまたは構造化ログを実装できるようになります。 書式設定されたメッセージ テンプレートだけでなく、引数自体がログ システムに渡されます。 これにより、ログ プロバイダーはフィールドとしてパラメーター値を格納することができます。 たとえば、次のロガー メソッドについて考えてみます。
_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);
たとえば、Azure Table Storage にログを記録する場合:
- 各 Azure Table エンティティには、
ID
プロパティとRequestTime
プロパティを含めることができます。 - プロパティを持つテーブルによって、ログに記録されたデータに対するクエリが簡略化されます。 たとえば、クエリによって、特定の
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 and ToCtxString は Rick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller
および Razor Page
ルート情報が表示されます。
例外ログはプロバイダー固有です。
既定のログ レベル
既定のログ レベルが設定されていない場合、既定のログ レベル値は Information
になります。
たとえば、次の Web アプリについて考えてみます。
- ASP.NET Web アプリ テンプレートを使用して作成された。
appsettings.json
とappsettings.Development.json
は削除されているか、名前が変更されている。
上記の設定で、privacy ページまたは home ページに移動すると、カテゴリ名に Microsoft
が含まれる多くの Trace
、Debug
、Information
のメッセージが生成されます。
次のコードは、既定のログ レベルが構成で設定されていない場合に、既定のログ レベルを設定します。
var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);
一般に、ログ レベルは、コードではなく構成で指定する必要があります。
フィルター関数
フィルター関数は、構成またはコードによって規則が割り当てられていないすべてのプロバイダーとカテゴリに対して呼び出されます。
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;
}
});
上記のコードでは、カテゴリに Controller
または Microsoft
が含まれ、ログ レベルが Information
以上の場合にコンソール ログが表示されます。
一般に、ログ レベルは、コードではなく構成で指定する必要があります。
ASP.NET Core のカテゴリ
次の表に、ASP.NET 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 |
提供されるファイル。 |
コンソール ウィンドウに他のカテゴリを表示するには、appsettings.Development.json
を次のように設定します。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Trace",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
Entity Framework カテゴリの一覧については、EF メッセージのカテゴリに関するページを参照してください。
ログのスコープ
"スコープ" では、論理操作のセットをグループ化できます。 このグループ化を使用して、セットの一部として作成される各ログに同じデータをアタッチすることができます。 たとえば、トランザクション処理の一部として作成されるすべてのログに、トランザクション ID を含めることができます。
スコープは:
- BeginScope メソッドによって返される IDisposable 型です。
- 破棄されるまで継続します。
次のプロバイダーではスコープがサポートされています。
ロガーの呼び出しを 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 および IIS での ASP.NET Core のトラブルシューティング」および「IIS の ASP.NET Core モジュール (ANCM)」を参照してください。
コンソール
Console
プロバイダーでは、コンソールへの出力がログに記録されます。 開発中の Console
ログを表示する方法の詳細については、「dotnet run および Visual Studio からのログ出力」を参照してください。
デバッグ
Debug
プロバイダーでは、System.Diagnostics.Debug クラスを使ってログ出力が書き込まれます。 Debug
プロバイダーに書き込むために System.Diagnostics.Debug.WriteLine
が呼び出されます。
Linux では、Debug
プロバイダーのログの場所は配布によって異なり、次のいずれかになります。
/var/log/message
/var/log/syslog
イベント ソース
EventSource
プロバイダーでは、Microsoft-Extensions-Logging
という名前のクロスプラットフォーム イベント ソースに書き込まれます。 Windows では、プロバイダーによって ETW が使用されます。
dotnet-trace ツール
dotnet-trace
ツールは、実行中のプロセスの .NET Core のトレースのコレクションを有効にする、クロスプラットフォームの CLI グローバル ツールです。 このツールでは、LoggingEventSource を使用して Microsoft.Extensions.Logging.EventSource プロバイダー データを収集します。
インストール手順については、「dotnet-trace
」をご覧ください。
dotnet-trace
ツールを使用して、アプリからトレースを収集します。
dotnet run
コマンドを使用してアプリを実行します。.NET Core アプリのプロセス識別子 (PID) を決定します。
dotnet-trace ps
アプリのアセンブリと同じ名前を持つプロセスの PID を検索します。
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
に変更します。次の表にキーワードを定義します。
Keyword 説明 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")
を呼び出している。 - プロセス ID (PID) が
set PID=12345
を介して設定されている。ここで、12345
は実際の PID を表します。
次のようなコマンドについて考えてみます。
dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
上記のコマンドでは次のことが行われます。
- デバッグ メッセージをキャプチャします。
FilterSpecs
は適用されません。- Debug カテゴリに対応するレベル 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
のログ記録。
Enter キーまたは Ctr+C キーを押すことで、
dotnet-trace
ツールを停止します。トレースは、
dotnet-trace
コマンドが実行されたフォルダーにtrace.nettrace
という名前で保存されます。Perfview を使用してトレースを開きます。
trace.nettrace
ファイルを開き、トレース イベントを調べます。
アプリで WebApplication.CreateBuilder を使ってホストがビルドされない場合は、イベント ソース プロバイダーをアプリのログ構成に追加します。
詳細については次を参照してください:
- パフォーマンス分析ユーティリティのトレース (
dotnet-trace
) (.NET Core ドキュメント) - パフォーマンス分析ユーティリティのトレース (
dotnet-trace
) (dotnet/diagnostics GitHub リポジトリ ドキュメント) - LoggingEventSource
- EventLevel
- Perfview:イベント ソース トレースの表示に役立ちます。
Perfview
ログの収集と表示には、PerfView ユーティリティを使用します。 ETW ログを表示できる他のツールはありますが、ASP.NET Core から出力される ETW イベントを操作する場合、PerfView は最適なエクスペリエンスを提供します。
このプロバイダーでログに記録されるイベントを収集するように 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
:"Application"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 ストレージにログを書き込みます。
プロバイダー パッケージは、共有フレームワークに含まれていません。 プロバイダーを使用するには、プロバイダー パッケージをプロジェクトに追加します。
プロバイダーの設定を構成するには、次の例のように AzureFileLoggerOptions と AzureBlobLoggerOptions を使用します。
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 portal の [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 ログのストリーミングでは、以下からのリアル タイムでのログ アクティビティの表示がサポートされています。
- アプリ サーバー
- Web サーバー
- 失敗した要求のトレース
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 Core ではなく、ASP.NET 4.x 用です。
詳細については、次のリソースを参照してください。
- Application Insights の概要
- Application Insights for ASP.NET Core アプリケーション: ログ記録と共に完全な Application Insights テレメトリを実装する場合は、ここから開始します。
- ApplicationInsightsLoggerProvider for .NET Core ILogger ログ: ログ プロバイダーを実装し、Application Insights テレメトリの rest の部分は除く場合は、ここから開始します。
- Application Insights のログ アダプター。
- Application Insights SDK のインストール、構成、および初期化 - 対話型のチュートリアルです。
サードパーティ製のログ プロバイダー
ASP.NET Core で使用できるサードパーティ製のログ記録フレームワークをいくつか紹介します。
- elmah.io (GitHub リポジトリ)
- Gelf (GitHub リポジトリ)
- JSNLog (GitHub リポジトリ)
- KissLog.net (GitHub リポジトリ)
- Log4Net (GitHub リポジトリ)
- NLog (GitHub リポジトリ)
- PLogger (GitHub リポジトリ)
- Sentry (GitHub リポジトリ)
- Serilog (GitHub リポジトリ)
- Stackdriver (Github リポジトリ)
一部のサードパーティ製フレームワークは、セマンティック ログ記録 (構造化ログ記録とも呼ばれます) を実行できます。
サード パーティ製フレームワークを使用することは、組み込みのプロバイダーのいずれかを使用することと似ています。
- プロジェクトに NuGet パッケージを追加します。
- ログ記録フレームワークによって提供される
ILoggerFactory
拡張メソッドを呼び出します。
詳細については、各プロバイダーのドキュメントをご覧ください。 サード パーティ製のログ プロバイダーは、Microsoft ではサポートされていません。
非同期でないロガー メソッド
ログ記録は高速に実行され、非同期コードのパフォーマンス コストを下回る必要があります。 ログ データ ストアが低速の場合は、そこへ直接書き込まないでください。 まずログ メッセージを高速なストアに書き込んでから、後で低速なストアに移動することを検討してください。 たとえば、SQL Server にログを記録する場合、Log
メソッドは同期しているため、Log
メソッドで直接それを行わないでください。 代わりに、ログ メッセージをインメモリ キューに同期的に追加し、バックグラウンド ワーカーにキューからメッセージをプルさせて、SQL Server にデータをプッシュする非同期処理を実行させます。 詳細については、低速なデータ ストアのメッセージ キューにログする方法についてのガイダンス (dotnet/AspNetCore.Docs #11801) に関するページを参照してください。
実行中のアプリのログ レベルを変更する
ログ API には、アプリの実行中にログ レベルを変更するシナリオは含まれていません。 ただし、一部の構成プロバイダーは構成を再読み込みすることができ、ログ構成に直ちに影響します。 たとえば、ファイル構成プロバイダーでは、既定でログ構成が再度読み込まれます。 アプリの実行中にコードの構成が変更された場合、アプリは IConfigurationRoot.Reload を呼び出して、アプリのログ構成を更新できます。
ILogger と ILoggerFactory
ILogger<TCategoryName> と ILoggerFactory のインターフェイスと実装は .NET Core SDK に含まれています。 これらは、次の NuGet パッケージでも入手できます。
- インターフェイスは
Microsoft.Extensions.Logging.Abstractions
にあります。 - 既定の実装は、
Microsoft.Extensions.Logging
にあります。
コードでログ フィルター規則を適用する
ログ フィルター規則を設定するには、構成を使用することをお勧めします。
コードにフィルター規則を登録する方法を次の例に示します。
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"
で始まるすべてのカテゴリ。
SpanId
、TraceId
、ParentId
、Baggage
、Tags
を使用してスコープを自動的にログする
ログ ライブラリでは、SpanId
、TraceId
、ParentId
、Baggage
、Tags
を使用してスコープ オブジェクトが暗黙的に作成されます。 この動作は、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 Larkin、Juergen Gutsch、Rick Anderson
このトピックでは、ASP.NET Core アプリに用いられる .NET のログについて説明します。 .NET のログの詳細については、「.NET でのログの記録」を参照してください。 Blazor アプリでのログについて詳しくは、「ASP.NET Core Blazor のログ」をご覧ください。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
ログ プロバイダー
ログを表示する Console
プロバイダーを除き、ログ プロバイダーはログを保存します。 たとえば、Azure Application Insights プロバイダーでは、Azure Application Insights にログが保存されます。 複数のプロバイダーを有効にすることができます。
既定の ASP.NET Core Web アプリ テンプレートでは:
- 汎用ホストが使用されます。
- CreateDefaultBuilder が呼び出されます。これにより、次のログ プロバイダーが追加されます。
- コンソール
- デバッグ
- EventSource
- EventLog:Windows のみ
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
を呼び出し、必要なログ プロバイダーを追加します。 コード例を次に示します。
- ClearProviders を呼び出して、ビルダーからすべての ILoggerProvider インスタンスを削除します。
- Console ログ プロバイダーを追加します。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
その他のプロバイダーについては、以下を参照してください。
ログを作成する
ログを作成するには、依存関係の挿入 (DI) から ILogger<TCategoryName> オブジェクトを使用します。
次のような例です。
AboutModel
型の完全修飾名のログ "カテゴリ" を使用する、ロガーILogger<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 Core Blazor のログ」をご覧ください。
Main および Startup でログを作成に関するセクションには、Main
と Startup
でログを作成する方法が示されています。
ログの構成
一般的に、ログの構成は appsettings.{Environment}.json
ファイルの Logging
セクションで指定されます。 ASP.NET Core の Web アプリ テンプレートによって、次の appsettings.Development.json
ファイルが生成されます。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
上記の JSON では、次のように指定されています。
"Default"
、"Microsoft"
、および"Microsoft.Hosting.Lifetime"
の各カテゴリが指定されています。"Microsoft"
カテゴリは、"Microsoft"
で始まるすべてのカテゴリに適用されます。 たとえば、この設定は"Microsoft.AspNetCore.Routing.EndpointMiddleware"
カテゴリに適用されます。"Microsoft"
カテゴリでは、ログ レベルがWarning
以上のログが記録されます。"Microsoft.Hosting.Lifetime"
カテゴリは"Microsoft"
カテゴリよりも詳細なので、"Microsoft.Hosting.Lifetime"
カテゴリではログ レベルが "情報" 以上のログが記録されます。- 特定のログ プロバイダーが指定されていないため、
LogLevel
は、Windows EventLog を除くすべての有効なログ プロバイダーに適用されます。
Logging
プロパティには LogLevel およびログ プロバイダーのプロパティを含めることができます。 LogLevel
により、選択したカテゴリに対するログの最小レベルが指定されます。 上記の JSON では、Information
と Warning
のログ レベルが指定されています。 LogLevel
はログの重大度を 0 - 6 の範囲で示します。
Trace
= 0、Debug
= 1、Information
= 2、Warning
= 3、Error
= 4、Critical
= 5、None
= 6。
LogLevel
を指定すると、指定したレベル以上のメッセージに対してログが有効になります。 上記の JSON では、Default
カテゴリは Information
以上に対してのみログに記録されます。 たとえば、Information
、Warning
、Error
、Critical
のメッセージがログに記録されます。 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
上記の設定により、Microsoft.Hosting
以外のすべての Logging:Debug:
カテゴリに Information
ログ レベルが指定されます。 特定のカテゴリが一覧表示されると、特定のカテゴリによって既定のカテゴリがオーバーライドされます。 上記の JSON では、Logging:Debug:LogLevel
カテゴリ "Microsoft.Hosting"
と "Default"
によって、Logging:LogLevel
の設定がオーバーライドされます。
最小ログ レベルは、次のいずれかに指定できます。
- 特定のプロバイダー: たとえば、
Logging:EventSource:LogLevel:Default:Information
- 特定のカテゴリ: たとえば、
Logging:LogLevel:Microsoft:Warning
- すべてのプロバイダーとすべてのカテゴリ:
Logging:LogLevel:Default:Warning
最小レベルを下回るログは、次のことが "行われません"。
- プロバイダーに渡される。
- ログに記録または表示される。
すべてのログを抑制するには、LogLevel.None を指定します。 LogLevel.None
の値は、LogLevel.Critical
(5) より大きい 6 です。
プロバイダーでログのスコープがサポートされている場合、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 アプリケーション テンプレートを使用して作成されたアプリを使用する際に、設定をテストします。
dotnet run
コマンドは、set
を使用した後、プロジェクト ディレクトリで実行する必要があります。
set Logging__LogLevel__Microsoft=Information
dotnet run
上記の環境設定は:
- コマンド ウィンドウから起動されたプロセスでのみ設定可能です。
- Visual Studio で起動されたブラウザーでは読み取れません。
次の setx コマンドは、Windows 上で環境キーと値も設定します。 set
とは異なり、setx
設定は保持されます。 /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 アプリケーションの設定は:
- rest に暗号化され、暗号化されたチャネルで送信されます。
- 環境変数として公開されます。
詳細については、「Azure アプリ: Azure Portal を使用してアプリの構成をオーバーライドする」を参照してください。
環境変数を使用して ASP.NET Core 構成値を設定する方法の詳細については、「環境変数」を参照してください。 コマンド ライン、Azure Key Vault、Azure App Configuration、その他のファイル形式など、他の構成ソースの使用の詳細については、「ASP.NET Core の構成」を参照してください。
フィルター規則を適用する方法
ILogger<TCategoryName> オブジェクトを作成すると、ILoggerFactory オブジェクトによって、そのロガーに適用するプロバイダーごとに 1 つの規則が選択されます。 ILogger
インスタンスによって書き込まれるすべてのメッセージは、選択した規則に基づいてフィルター処理されます。 使用できる規則から、各プロバイダーとカテゴリのペアごとに最も明確な規則が選択されます。
特定のカテゴリに ILogger
が作成されるときに、各プロバイダーに次のアルゴリズムが使用されます。
- プロバイダーとそのエイリアスと一致するすべての規則が選択されます。 一致が見つからない場合は、空のプロバイダーですべての規則が選択されます。
- 前の手順の結果、最も長いカテゴリのプレフィックスが一致する規則が選択されます。 一致が見つからない場合は、カテゴリを指定しないすべての規則が選択されます。
- 複数の規則が選択されている場合は、最後の 1 つが使用されます。
- 規則が選択されていない場合は、
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>
を使用して、カテゴリとして T
の完全修飾型名を使用する ILogger
インスタンスが自動的に取得されます。
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 | [値] | Method | 説明 |
---|---|---|---|
トレース | 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 が指定されます。 たとえば、次の 2 つのログ呼び出しは、機能的に同等で、同じログが生成されます。
[HttpGet]
public IActionResult Test1(int id)
{
var routeInfo = ControllerContext.ToCtxString(id);
_logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
_logger.LogInformation(MyLogEvents.TestItem, routeInfo);
return ControllerContext.MyDisplayRouteInfo();
}
MyLogEvents.TestItem
はイベント ID です。 MyLogEvents
はサンプル アプリの一部であり、ログ イベント ID セクションに表示されます。
MyDisplayRouteInfo and ToCtxString は Rick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller
および Razor Page
ルート情報が表示されます。
Information
および Warning
ログを作成するコードを次に示します。
[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
は、ログ イベント ID です。 2 つ目のパラメーターは、他のメソッド パラメーターによって提供される引数値のプレースホルダーを含むメッセージ テンプレートです。 メソッド パラメーターについては、このドキュメントで後述するメッセージ テンプレートのセクションで説明します。
適切な Log{LogLevel}
メソッドを呼び出して、特定のストレージ メディアに書き込むログ出力量を制御します。 次に例を示します。
- 運用環境:
Trace
またはInformation
のレベルでログを記録すると、詳細なログ メッセージが大量に生成されます。 コストを制御し、データ ストレージの上限を超えないようにするには、Trace
およびInformation
のレベルのメッセージを、大容量の低コストのデータ ストアに記録します。Trace
とInformation
を特定のカテゴリに制限することを検討してください。Warning
からCritical
のレベルでログを記録しても、ログ メッセージはほとんど生成されません。- 通常、コストとストレージの制限は考慮されません。
- ログの数が少ないほど、データ ストアをより柔軟に選択できるようになります。
- 開発中:
Warning
に設定します。- トラブルシューティングの際に
Trace
またはInformation
のメッセージを追加します。 出力を制限するには、調査中のカテゴリに対してのみTrace
またはInformation
を設定します。
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"
}
}
}
}
ログ イベント ID
各ログで "イベント ID" を指定できます。 このサンプル アプリでは、MyLogEvents
クラスを使用してイベント ID を定義します。
public class MyLogEvents
{
public const int GenerateItems = 1000;
public const int ListItems = 1001;
public const int GetItem = 1002;
public const int InsertItem = 1003;
public const int UpdateItem = 1004;
public const int DeleteItem = 1005;
public const int TestItem = 3000;
public const int GetItemNotFound = 4000;
public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
_logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
_logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
return NotFound();
}
return ItemToDTO(todoItem);
}
イベント ID によって一連のイベントが関連付けられます。 たとえば、ページ上に項目の一覧を表示する機能に関連するすべてのログを 1001 に設定します。
ログ プロバイダーでは、ID フィールドやログ メッセージにイベント ID が格納されたり、またはまったく格納されなかったりする場合があります。 Debug プロバイダーでイベント ID が表示されることはありません。 Console プロバイダーでは、カテゴリの後のブラケット内にイベント ID が表示されます。
info: TodoApi.Controllers.TodoItemsController[1002]
Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
Get(1) NOT FOUND
一部のログ プロバイダーでは、イベント ID がフィールドに格納されます。これにより、ID に対するフィルター処理が可能になります。
ログ メッセージ テンプレート
各ログ 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);
しかし、プレースホルダーには、apples
、pears
、bananas
という順序でパラメーターが割り当てられます。 ログ メッセージに、パラメーターの順序が反映されています。
Parameters: 1, 2, 3
この方法により、ログ プロバイダーが セマンティック ログまたは構造化ログを実装できるようになります。 書式設定されたメッセージ テンプレートだけでなく、引数自体がログ システムに渡されます。 これにより、ログ プロバイダーはフィールドとしてパラメーター値を格納することができます。 たとえば、次のロガー メソッドについて考えてみます。
_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);
たとえば、Azure Table Storage にログを記録する場合:
- 各 Azure Table エンティティには、
ID
プロパティとRequestTime
プロパティを含めることができます。 - プロパティを持つテーブルによって、ログに記録されたデータに対するクエリが簡略化されます。 たとえば、クエリによって、特定の
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 and ToCtxString は Rick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller
および Razor Page
ルート情報が表示されます。
例外ログはプロバイダー固有です。
既定のログ レベル
既定のログ レベルが設定されていない場合、既定のログ レベル値は Information
になります。
たとえば、次の Web アプリについて考えてみます。
- ASP.NET Web アプリ テンプレートを使用して作成された。
appsettings.json
とappsettings.Development.json
は削除されているか、名前が変更されている。
上記の設定で、privacy ページまたは home ページに移動すると、カテゴリ名に Microsoft
が含まれる多くの Trace
、Debug
、Information
のメッセージが生成されます。
次のコードは、既定のログ レベルが構成で設定されていない場合に、既定のログ レベルを設定します。
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>();
});
}
一般に、ログ レベルは、コードではなく構成で指定する必要があります。
フィルター関数
フィルター関数は、構成またはコードによって規則が割り当てられていないすべてのプロバイダーとカテゴリに対して呼び出されます。
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>();
});
}
上記のコードでは、カテゴリに Controller
または Microsoft
が含まれ、ログ レベルが 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"
}
}
}
ログのスコープ
"スコープ" では、論理操作のセットをグループ化できます。 このグループ化を使用して、セットの一部として作成される各ログに同じデータをアタッチすることができます。 たとえば、トランザクション処理の一部として作成されるすべてのログに、トランザクション ID を含めることができます。
スコープは:
- BeginScope メソッドによって返される IDisposable 型です。
- 破棄されるまで継続します。
次のプロバイダーではスコープがサポートされています。
ロガーの呼び出しを 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 および IIS での ASP.NET Core のトラブルシューティング」および「IIS の ASP.NET Core モジュール (ANCM)」を参照してください。
コンソール
Console
プロバイダーでは、コンソールへの出力がログに記録されます。 開発中の Console
ログを表示する方法の詳細については、「dotnet run および Visual Studio からのログ出力」を参照してください。
デバッグ
Debug
プロバイダーでは、System.Diagnostics.Debug クラスを使ってログ出力が書き込まれます。 Debug
プロバイダーに書き込むために System.Diagnostics.Debug.WriteLine
が呼び出されます。
Linux では、Debug
プロバイダーのログの場所は配布によって異なり、次のいずれかになります。
- /var/log/message
- /var/log/syslog
イベント ソース
EventSource
プロバイダーでは、Microsoft-Extensions-Logging
という名前のクロスプラットフォーム イベント ソースに書き込まれます。 Windows では、プロバイダーによって ETW が使用されます。
dotnet trace ツール
dotnet-trace ツールは、実行中のプロセスの .NET Core のトレースのコレクションを有効にする、クロスプラットフォームの CLI グローバル ツールです。 このツールでは、LoggingEventSource を使用して Microsoft.Extensions.Logging.EventSource プロバイダー データを収集します。
インストール手順については、dotnet-trace に関するページを参照してください。
dotnet trace ツールを使用して、アプリからトレースを収集します。
dotnet run
コマンドを使用してアプリを実行します。.NET Core アプリのプロセス識別子 (PID) を決定します。
dotnet trace ps
アプリのアセンブリと同じ名前を持つプロセスの PID を検索します。
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
に変更します。次の表にキーワードを定義します。
Keyword 説明 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")
を呼び出している。 - プロセス ID (PID) が
set PID=12345
を介して設定されている。ここで、12345
は実際の PID を表します。
次のようなコマンドについて考えてみます。
dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
上記のコマンドでは次のことが行われます。
- デバッグ メッセージをキャプチャします。
FilterSpecs
は適用されません。- Debug カテゴリに対応するレベル 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
のログ記録。
Enter キーまたは Ctrl + C キーを押すことで、dotnet trace ツールを停止します。
トレースは、
dotnet trace
コマンドが実行されたフォルダーに trace.nettrace という名前で保存されます。Perfview を使用してトレースを開きます。 trace.nettrace ファイルを開き、トレース イベントを調べます。
アプリで CreateDefaultBuilder
を使ってホストがビルドされない場合は、イベント ソース プロバイダーをアプリのログ構成に追加します。
詳細については次を参照してください:
- パフォーマンス分析ユーティリティのトレース (dotnet-trace) (.NET Core ドキュメント)
- パフォーマンス分析ユーティリティのトレース (dotnet-trace) (dotnet/diagnostics GitHub リポジトリ ドキュメント)
- LoggingEventSource クラス (.NET API ブラウザー)
- EventLevel
- LoggingEventSource 参照ソース (3.0):別のバージョンの参照ソースを取得するには、分岐を
release/{Version}
に変更します。ここでは、{Version}
は目的の ASP.NET Core のバージョンです。 - Perfview:イベント ソース トレースの表示に役立ちます。
Perfview
ログの収集と表示には、PerfView ユーティリティを使用します。 ETW ログを表示できる他のツールはありますが、ASP.NET Core から出力される ETW イベントを操作する場合、PerfView は最適なエクスペリエンスを提供します。
このプロバイダーでログに記録されるイベントを収集するように 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
:"Application"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 Storage アカウントの BLOB ストレージにログを書き込みます。
プロバイダー パッケージは、共有フレームワークに含まれていません。 プロバイダーを使用するには、プロバイダー パッケージをプロジェクトに追加します。
プロバイダーの設定を構成するには、次の例のように AzureFileLoggerOptions と AzureBlobLoggerOptions を使用します。
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 portal の [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 ログのストリーミングでは、以下からのリアル タイムでのログ アクティビティの表示がサポートされています。
- アプリ サーバー
- Web サーバー
- 失敗した要求のトレース
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 Core ではなく、ASP.NET 4.x 用です。
詳細については、次のリソースを参照してください。
- Application Insights の概要
- Application Insights for ASP.NET Core アプリケーション - ログ記録と共に完全な Application Insights テレメトリを実装する場合は、ここから開始します。
- ApplicationInsightsLoggerProvider for .NET Core ILogger ログ - ログ プロバイダーを実装し、Application Insights テレメトリの rest の部分は除く場合は、ここから開始します。
- Application Insights のログ アダプター。
- Application Insights SDK のインストール、構成、および初期化 - 対話型のチュートリアルです。
サードパーティ製のログ プロバイダー
ASP.NET Core で使用できるサードパーティ製のログ記録フレームワークをいくつか紹介します。
- elmah.io (GitHub リポジトリ)
- Gelf (GitHub リポジトリ)
- JSNLog (GitHub リポジトリ)
- KissLog.net (GitHub リポジトリ)
- Log4Net (GitHub リポジトリ)
- NLog (GitHub リポジトリ)
- PLogger (GitHub リポジトリ)
- Sentry (GitHub リポジトリ)
- Serilog (GitHub リポジトリ)
- Stackdriver (Github リポジトリ)
一部のサードパーティ製フレームワークは、セマンティック ログ記録 (構造化ログ記録とも呼ばれます) を実行できます。
サード パーティ製フレームワークを使用することは、組み込みのプロバイダーのいずれかを使用することと似ています。
- プロジェクトに NuGet パッケージを追加します。
- ログ記録フレームワークによって提供される
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> オブジェクトを使用します。 ILogger
を作成するには、LoggerFactory
を使用します。
次の例では、カテゴリが 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");
}
}
レベルとカテゴリについては、このドキュメントで詳しく説明しています。
ホストの構築時のログ記録
ホストの構築時のログ記録は、直接サポートされていません。 ただし、別のロガーを使用することができます。 次の例では、CreateHostBuilder
でログを記録するために、Serilog ロガーが使用されています。 AddSerilog
では、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 に依存するサービスを構成する
ASP.NET Core の以前のバージョンでは Web ホスト用に別の DI コンテナーが作成されるため、ロガーの Startup
へのコンストラクター挿入が機能します。 汎用ホストに対して 1 つのコンテナーのみが作成される理由については、破壊的変更に関するお知らせに関する記事を参照してください。
ILogger<T>
に依存するサービスを構成するには、コンストラクターの挿入を使用するか、ファクトリ メソッドを指定します。 ファクトリ メソッドの方法は、他の選択肢がない場合にのみお勧めします。 たとえば、DI によって提供される ILogger<T>
インスタンスを必要とするサービスについて考えてみます。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddRazorPages();
services.AddSingleton<IMyService>((container) =>
{
var logger = container.GetRequiredService<ILogger<MyService>>();
return new MyService() { Logger = logger };
});
}
前の強調表示されているコードは、DI コンテナーで MyService
のインスタンスが初めて作成されるときに実行される Func<T,TResult> です。 この方法では、任意の登録済みサービスにアクセスできます。
Main でログを作成する
次のコードでは、ホストを構築した後に DI から ILogger
インスタンスを取得することによって Main
でログを記録します。
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 でログを作成する
次のコードは、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 に依存しているためです。 DI コンテナーは、ConfigureServices
が完了するまで設定されません。
ILogger<T>
に依存するサービスの構成、または Startup
へのロガーのコンストラクター挿入が以前のバージョンで機能した理由については、ILogger に依存するサービスの構成に関するページを参照してください。
非同期でないロガー メソッド
ログ記録は高速に実行され、非同期コードのパフォーマンス コストを下回る必要があります。 ログ データ ストアが低速の場合は、そこへ直接書き込まないでください。 まずログ メッセージを高速なストアに書き込んでから、後で低速なストアに移動することを検討してください。 たとえば、SQL Server にログを記録する場合、Log
メソッドは同期しているため、Log
メソッドで直接それを行わないでください。 代わりに、ログ メッセージをインメモリ キューに同期的に追加し、バックグラウンド ワーカーにキューからメッセージをプルさせて、SQL Server にデータをプッシュする非同期処理を実行させます。 詳細については、この GitHub の問題を参照してください。
実行中のアプリのログ レベルを変更する
ログ API には、アプリの実行中にログ レベルを変更するシナリオは含まれていません。 ただし、一部の構成プロバイダーは構成を再読み込みすることができ、ログ構成に直ちに影響します。 たとえば、ファイル構成プロバイダーでは、既定でログ構成が再度読み込まれます。 アプリの実行中にコードの構成が変更された場合、アプリは IConfigurationRoot.Reload を呼び出して、アプリのログ構成を更新できます。
ILogger と ILoggerFactory
ILogger<TCategoryName> と ILoggerFactory のインターフェイスと実装は .NET Core SDK に含まれています。 これらは、次の NuGet パッケージでも入手できます。
- インターフェイスは、Microsoft.Extensions.Logging.Abstractions にあります。
- 既定の実装は、Microsoft.Extensions.Logging にあります。
コードでログ フィルター規則を適用する
ログ フィルター規則を設定するには、構成を使用することをお勧めします。
コードにフィルター規則を登録する方法を次の例に示します。
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 を使用してスコープを自動的にログする
ログ ライブラリでは、SpanId
、TraceId
、ParentId
を使用してスコープ オブジェクトが暗黙的に作成されます。 この動作は、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 にカスタム ログ プロバイダーを実装する」を参照してください。
その他のリソース
- ハイ パフォーマンスのログ
- ログのバグは、github.com/dotnet/runtime/ リポジトリに作成する必要があります。
- ASP.NET Core Blazor のログ
ASP.NET Core